1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Use of this source code is governed by a BSD-style license that can be
3ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// found in the LICENSE file.
4ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/webui/chromeos/imageburner_ui.h"
6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <algorithm>
8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/i18n/rtl.h"
10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/singleton.h"
11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/message_loop.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/path_service.h"
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/string_util.h"
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/task.h"
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/utf_string_conversions.h"
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/values.h"
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/download/download_types.h"
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/download/download_util.h"
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/profiles/profile.h"
20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/common/chrome_paths.h"
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/common/jstemplate_builder.h"
22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/common/url_constants.h"
23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/common/zip.h"
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/browser_thread.h"
25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/tab_contents/tab_contents.h"
26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "grit/browser_resources.h"
27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "grit/generated_resources.h"
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "grit/locale_settings.h"
29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "ui/base/l10n/l10n_util.h"
30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "ui/base/resource/resource_bundle.h"
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const char kPropertyPath[] = "path";
33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const char kPropertyTitle[] = "title";
34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const char kPropertyDirectory[] = "isDirectory";
35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const char kImageBaseURL[] =
36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    "http://chrome-master.mtv.corp.google.com/chromeos/dev-channel/";
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const char kImageFetcherName[] = "LATEST-x86-generic";
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const char kImageDownloadURL[] =
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    "https://dl.google.com/dl/chromeos/recovery/latest_mario_beta_channel";
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const char kImageFileName[] = "chromeos_image.bin.zip";
41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const char kTempImageFolderName[] = "chromeos_image";
42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen////////////////////////////////////////////////////////////////////////////////
44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//
45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// ImageBurnUIHTMLSource
46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//
47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen////////////////////////////////////////////////////////////////////////////////
48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass ImageBurnUIHTMLSource : public ChromeURLDataManager::DataSource {
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public:
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ImageBurnUIHTMLSource()
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      : DataSource(chrome::kChromeUIImageBurnerHost, MessageLoop::current()) {
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Called when the network layer has requested a resource underneath
56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // the path we registered.
57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void StartDataRequest(const std::string& path,
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                bool is_incognito,
59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                int request_id) {
60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DictionaryValue localized_strings;
61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    localized_strings.SetString("burnConfirmText1",
62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        l10n_util::GetStringUTF16(IDS_IMAGEBURN_CONFIM_BURN1));
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    localized_strings.SetString("burnConfirmText2",
64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        l10n_util::GetStringUTF16(IDS_IMAGEBURN_CONFIM_BURN2));
65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    localized_strings.SetString("burnUnsuccessfulMessage",
66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        l10n_util::GetStringUTF16(IDS_IMAGEBURN_BURN_UNSUCCESSFUL));
67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    localized_strings.SetString("burnSuccessfulMessage",
68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        l10n_util::GetStringUTF16(IDS_IMAGEBURN_BURN_SUCCESSFUL));
69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    localized_strings.SetString("downloadAbortedMessage",
70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        l10n_util::GetStringUTF16(IDS_IMAGEBURN_DOWNLOAD_UNSUCCESSFUL));
71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    localized_strings.SetString("title",
72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        l10n_util::GetStringUTF16(IDS_IMAGEBURN_TITLE));
73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    localized_strings.SetString("listTitle",
74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        l10n_util::GetStringUTF16(IDS_IMAGEBURN_ROOT_LIST_TITLE));
75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    localized_strings.SetString("downloadStatusStart",
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        l10n_util::GetStringUTF16(IDS_IMAGEBURN_DOWNLOAD_STARTING_STATUS));
77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    localized_strings.SetString("downloadStatusInProgress",
78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        l10n_util::GetStringUTF16(IDS_IMAGEBURN_DOWNLOAD_IN_PROGRESS_STATUS));
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    localized_strings.SetString("downloadStatusComplete",
80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        l10n_util::GetStringUTF16(IDS_IMAGEBURN_DOWNLOAD_COMPLETE_STATUS));
81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    localized_strings.SetString("downloadStatusCanceled",
82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        l10n_util::GetStringUTF16(IDS_IMAGEBURN_DOWNLOAD_CANCELED_STATUS));
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    localized_strings.SetString("burnStatusStart",
84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        l10n_util::GetStringUTF16(IDS_IMAGEBURN_BURN_STARTING_STATUS));
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    localized_strings.SetString("burnStatusInProgress",
86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        l10n_util::GetStringUTF16(IDS_IMAGEBURN_BURN_IN_PROGRESS_STATUS));
87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    localized_strings.SetString("burnStatusComplete",
88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        l10n_util::GetStringUTF16(IDS_IMAGEBURN_BURN_COMPLETE_STATUS));
89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    localized_strings.SetString("burnStatusCanceled",
90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        l10n_util::GetStringUTF16(IDS_IMAGEBURN_BURN_CANCELED_STATUS));
91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SetFontAndTextDirection(&localized_strings);
93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    static const base::StringPiece imageburn_html(
95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        ResourceBundle::GetSharedInstance().GetRawDataResource(
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        IDR_IMAGEBURNER_HTML));
97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const std::string full_html = jstemplate_builder::GetI18nTemplateHtml(
98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        imageburn_html, &localized_strings);
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    html_bytes->data.resize(full_html.size());
102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SendResponse(request_id, html_bytes);
105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual std::string GetMimeType(const std::string&) const {
108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return "text/html";
109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen private:
112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual ~ImageBurnUIHTMLSource() {}
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DISALLOW_COPY_AND_ASSIGN(ImageBurnUIHTMLSource);
115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen////////////////////////////////////////////////////////////////////////////////
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//
119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// ImageBurnTaskProxy
120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen////////////////////////////////////////////////////////////////////////////////
122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass ImageBurnTaskProxy
124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  : public base::RefCountedThreadSafe<ImageBurnTaskProxy> {
125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public:
126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  explicit ImageBurnTaskProxy(const base::WeakPtr<ImageBurnHandler>& handler)
127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      : handler_(handler) {}
128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void CreateImageDir() {
130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (handler_)
131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      handler_->CreateImageDirOnFileThread(this);
132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void OnImageDirCreated(bool success) {
135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (handler_)
136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      handler_->OnImageDirCreatedOnUIThread(success);
137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void BurnImage() {
140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (handler_)
141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      handler_->BurnImageOnFileThread();
142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DeleteOnUIThread();
143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void UnzipImage() {
146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (handler_)
147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      handler_->UnzipImageOnFileThread(this);
148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void UnzipComplete(bool success) {
151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (handler_)
152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      handler_->UnzipComplete(success);
153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // ImageBurnTaskProxy is created on the UI thread, so in some cases,
156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // we need to post back to the UI thread for destruction.
157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void DeleteOnUIThread() {
158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread::PostTask(
159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        BrowserThread::UI, FROM_HERE,
160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        NewRunnableMethod(this, &ImageBurnTaskProxy::DoNothing));
161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void DoNothing() {}
164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen private:
166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::WeakPtr<ImageBurnHandler> handler_;
167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  friend class base::RefCountedThreadSafe<ImageBurnTaskProxy>;
169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ~ImageBurnTaskProxy() {}
170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DISALLOW_COPY_AND_ASSIGN(ImageBurnTaskProxy);
172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen////////////////////////////////////////////////////////////////////////////////
175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//
176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// ImageBurnHandler
177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//
178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen////////////////////////////////////////////////////////////////////////////////
179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenImageBurnHandler::ImageBurnHandler(TabContents* contents)
181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    :tab_contents_(contents),
182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     download_manager_(NULL),
183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     download_item_observer_added_(false),
184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     active_download_item_(NULL),
185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     resource_manager_(NULL) {
186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  chromeos::CrosLibrary::Get()->GetMountLibrary()->AddObserver(this);
187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  chromeos::CrosLibrary::Get()->GetBurnLibrary()->AddObserver(this);
188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  resource_manager_ = ImageBurnResourceManager::GetInstance();
189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  zip_image_file_path_.clear();
190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  image_file_path_.clear();
191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  image_target_.clear();
192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenImageBurnHandler::~ImageBurnHandler() {
195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  chromeos::CrosLibrary::Get()->GetMountLibrary()->RemoveObserver(this);
196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  chromeos::CrosLibrary::Get()->GetBurnLibrary()->RemoveObserver(this);
197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (active_download_item_)
198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    active_download_item_->RemoveObserver(this);
199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (download_manager_)
200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      download_manager_->RemoveObserver(this);
201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenWebUIMessageHandler* ImageBurnHandler::Attach(WebUI* web_ui) {
204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return WebUIMessageHandler::Attach(web_ui);
205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::RegisterMessages() {
208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  web_ui_->RegisterMessageCallback("getRoots",
209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NewCallback(this, &ImageBurnHandler::HandleGetRoots));
210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  web_ui_->RegisterMessageCallback("downloadImage",
211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NewCallback(this, &ImageBurnHandler::HandleDownloadImage));
212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  web_ui_->RegisterMessageCallback("burnImage",
213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NewCallback(this, &ImageBurnHandler::HandleBurnImage));
214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  web_ui_->RegisterMessageCallback("cancelBurnImage",
215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NewCallback(this, &ImageBurnHandler::HandleCancelBurnImage));
216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::DiskChanged(chromeos::MountLibraryEventType event,
219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                   const chromeos::MountLibrary::Disk* disk) {
220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (event == chromeos::MOUNT_DISK_REMOVED ||
221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      event == chromeos::MOUNT_DISK_CHANGED ||
222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      event == chromeos::MOUNT_DISK_UNMOUNTED) {
223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    web_ui_->CallJavascriptFunction("rootsChanged");
224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::DeviceChanged(chromeos::MountLibraryEventType event,
228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                     const std::string& device_path) {
229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (event == chromeos::MOUNT_DEVICE_REMOVED)
230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    web_ui_->CallJavascriptFunction("rootsChanged");
231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::ProgressUpdated(chromeos::BurnLibrary* object,
235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                       chromeos::BurnEventType evt,
236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                       const ImageBurnStatus& status) {
237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  UpdateBurnProgress(status.amount_burnt, status.total_size,
238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                     status.target_path, evt);
239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (evt == chromeos::BURN_COMPLETE) {
240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    FinalizeBurn(true);
241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else if (evt == chromeos::BURN_CANCELED) {
242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    FinalizeBurn(false);
243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::OnDownloadUpdated(DownloadItem* download) {
247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (download->IsCancelled()) {
248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DownloadCompleted(false);  // Should stop observation.
249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(!download_item_observer_added_);
250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else if (download->IsComplete()) {
251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    zip_image_file_path_ = download->full_path();
252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DownloadCompleted(true);  // Should stop observation.
253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(!download_item_observer_added_);
254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else if (download->IsPartialDownload()) {
255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      scoped_ptr<DictionaryValue> result_value(
256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          download_util::CreateDownloadItemValue(download, 0));
257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      web_ui_->CallJavascriptFunction("downloadUpdated", *result_value);
258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::OnDownloadOpened(DownloadItem* download) {
262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (download->safety_state() == DownloadItem::DANGEROUS)
263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    download->DangerousDownloadValidated();
264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::ModelChanged() {
267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Find our item and observe it.
268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<DownloadItem*> downloads;
269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  download_manager_->GetTemporaryDownloads(
270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      resource_manager_->GetImageDir(), &downloads);
271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (download_item_observer_added_)
272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (std::vector<DownloadItem*>::const_iterator it = downloads.begin();
274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      it != downloads.end();
275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ++it) {
276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if ((*it)->original_url() == *image_download_url_) {
277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      download_item_observer_added_ = true;
278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      (*it)->AddObserver(this);
279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      active_download_item_ = *it;
280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      break;
281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
285ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::OnImageDirCreated(bool success,
286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                         ImageBurnTaskProxy* task) {
287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Transfer to UI thread.
289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BrowserThread::PostTask(
290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      BrowserThread::UI, FROM_HERE,
291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NewRunnableMethod(task, &ImageBurnTaskProxy::OnImageDirCreated,
292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        success));
293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::OnDownloadStarted(bool success) {
296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (success)
297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    resource_manager_->set_download_started(true);
298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  else
299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DownloadCompleted(false);
300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::HandleGetRoots(const ListValue* args) {
303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ListValue results_value;
304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DictionaryValue info_value;
305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  chromeos::MountLibrary* mount_lib =
306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      chromeos::CrosLibrary::Get()->GetMountLibrary();
307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const chromeos::MountLibrary::DiskMap& disks = mount_lib->disks();
308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!resource_manager_->burn_in_progress()) {
309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (chromeos::MountLibrary::DiskMap::const_iterator iter =  disks.begin();
310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         iter != disks.end();
311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         ++iter) {
312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (iter->second->is_parent()) {
313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        FilePath disk_path = FilePath(iter->second->system_path()).DirName();
314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        std::string title = "/dev/" + disk_path.BaseName().value();
315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (!iter->second->on_boot_device()) {
316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          DictionaryValue* page_value = new DictionaryValue();
317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          page_value->SetString(std::string(kPropertyTitle), title);
318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          page_value->SetString(std::string(kPropertyPath), title);
319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          page_value->SetBoolean(std::string(kPropertyDirectory), true);
320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          results_value.Append(page_value);
321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  info_value.SetString("functionCall", "getRoots");
327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  info_value.SetString(std::string(kPropertyPath), "");
328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  web_ui_->CallJavascriptFunction("browseFileResult",
329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                  info_value, results_value);
330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::HandleDownloadImage(const ListValue* args) {
333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ExtractTargetedDeviceSystemPath(args);
334ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (resource_manager_->GetImageDir().empty()) {
335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Create image dir on File thread.
336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    scoped_refptr<ImageBurnTaskProxy> task =
337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        new ImageBurnTaskProxy(AsWeakPtr());
338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread::PostTask(
339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        BrowserThread::FILE, FROM_HERE,
340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        NewRunnableMethod(task.get(), &ImageBurnTaskProxy::CreateImageDir));
341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    OnImageDirCreatedOnUIThread(true);
343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
345ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
346ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::DownloadCompleted(bool success) {
347ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  resource_manager_->SetDownloadFinished(success);
348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (active_download_item_) {
349ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    active_download_item_->RemoveObserver(this);
350ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    active_download_item_ = NULL;
351ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
352ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  download_item_observer_added_ = false;
353ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (download_manager_)
354ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    download_manager_->RemoveObserver(this);
355ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
356ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (success) {
357ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    UnzipImage();
358ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
359ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    UnzipComplete(success);
360ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
361ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
362ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::UnzipComplete(bool success) {
364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
365ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
366ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DictionaryValue signal_value;
367ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (success) {
368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    signal_value.SetString("state", "COMPLETE");
369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    web_ui_->CallJavascriptFunction("downloadUpdated", signal_value);
370ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    web_ui_->CallJavascriptFunction("promptUserDownloadFinished");
371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    signal_value.SetString("state", "CANCELLED");
373ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    web_ui_->CallJavascriptFunction("downloadUpdated", signal_value);
374ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    web_ui_->CallJavascriptFunction("alertUserDownloadAborted");
375ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
376ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
377ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
378ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::HandleBurnImage(const ListValue* args) {
379ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<ImageBurnTaskProxy> task = new ImageBurnTaskProxy(AsWeakPtr());
380ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BrowserThread::PostTask(
381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        BrowserThread::FILE, FROM_HERE,
382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        NewRunnableMethod(task.get(), &ImageBurnTaskProxy::BurnImage));
383ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
384ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
385ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::HandleCancelBurnImage(const ListValue* args) {
386ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  image_target_.clear();
387ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
388ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
389ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::CreateImageDirOnFileThread(ImageBurnTaskProxy* task) {
390ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
391ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
392ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  resource_manager_->CreateImageDir(this, task);
393ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
394ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
395ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::OnImageDirCreatedOnUIThread(bool success) {
396ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
397ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (success) {
398ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    zip_image_file_path_ =
399ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        resource_manager_->GetImageDir().Append(kImageFileName);
400ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    resource_manager_->CreateImageUrl(tab_contents_, this);
401ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
402ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DownloadCompleted(success);
403ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
404ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
405ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
406ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::BurnImageOnFileThread() {
407ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
408ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
409ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (resource_manager_->burn_in_progress())
410ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
411ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  resource_manager_->set_burn_in_progress(true);
412ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
413ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (chromeos::CrosLibrary::Get()->GetBurnLibrary()->
414ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      DoBurn(image_file_path_, image_target_)) {
415ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DictionaryValue signal_value;
416ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    signal_value.SetString("state", "IN_PROGRESS");
417ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    signal_value.SetString("path", image_target_.value());
418ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    signal_value.SetInteger("received", 0);
419ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    signal_value.SetString("progress_status_text", "");
420ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    web_ui_->CallJavascriptFunction("burnProgressUpdated", signal_value);
421ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
422ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
423ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
424ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::FinalizeBurn(bool successful) {
425ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
426ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  web_ui_->CallJavascriptFunction(successful ? "burnSuccessful"
427ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                             : "burnUnsuccessful");
428ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  resource_manager_->set_burn_in_progress(false);
429ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
430ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
431ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::UpdateBurnProgress(int64 total_burnt,
432ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                          int64 image_size,
433ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                          const std::string& path,
434ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                          chromeos::BurnEventType event) {
435ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DictionaryValue progress_value;
436ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  progress_value.SetString("progress_status_text",
437ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      GetBurnProgressText(total_burnt, image_size));
438ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (event == chromeos::BURN_UPDATED)
439ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    progress_value.SetString("state", "IN_PROGRESS");
440ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  else if (event == chromeos::BURN_CANCELED)
441ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    progress_value.SetString("state", "CANCELLED");
442ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  else if (event == chromeos::BURN_COMPLETE)
443ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    progress_value.SetString("state", "COMPLETE");
444ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  progress_value.SetInteger("received", total_burnt);
445ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  progress_value.SetInteger("total", image_size);
446ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  progress_value.SetString("path", path);
447ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
448ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  web_ui_->CallJavascriptFunction("burnProgressUpdated", progress_value);
449ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
450ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
451ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstring16 ImageBurnHandler::GetBurnProgressText(int64 total_burnt,
452ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                               int64 image_size) {
453ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DataUnits amount_units = GetByteDisplayUnits(total_burnt);
454ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  string16 burnt_size = FormatBytes(total_burnt, amount_units, true);
455ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
456ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::i18n::AdjustStringForLocaleDirection(&burnt_size);
457ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
458ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (image_size) {
459ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    amount_units = GetByteDisplayUnits(image_size);
460ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    string16 total_text = FormatBytes(image_size, amount_units, true);
461ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::i18n::AdjustStringForLocaleDirection(&total_text);
462ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
463ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return l10n_util::GetStringFUTF16(IDS_IMAGEBURN_BURN_PROGRESS,
464ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                      burnt_size,
465ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                      total_text);
466ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
467ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return l10n_util::GetStringFUTF16(IDS_IMAGEBURN_BURN_PROGRESS_SIZE_UNKNOWN,
468ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                      burnt_size);
469ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
470ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
471ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
472ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::OnImageUrlCreated(GURL* image_url, bool success) {
473ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!success) {
474ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DownloadCompleted(false);
475ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
476ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
477ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  image_download_url_ = image_url;
478ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
479ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  download_manager_ = tab_contents_->profile()->GetDownloadManager();
480ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  download_manager_->AddObserver(this);
481ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
482ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!resource_manager_->download_started()) {
483ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    resource_manager_->set_download_started(true);
484ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!resource_manager_->image_download_requested()) {
485ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      resource_manager_->set_image_download_requested(true);
486ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ImageBurnDownloader::GetInstance()->AddListener(this,
487ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          *image_download_url_);
488ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ImageBurnDownloader::GetInstance()->DownloadFile(*image_download_url_,
489ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                                       zip_image_file_path_,
490ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                                       tab_contents_);
491ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
492ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else if (resource_manager_->download_finished()) {
493ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DownloadCompleted(true);
494ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
495ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
496ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
497ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::ExtractTargetedDeviceSystemPath(
498ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const ListValue* list_value) {
499ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Value* list_member;
500ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (list_value->Get(0, &list_member) &&
501ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      list_member->GetType() == Value::TYPE_STRING) {
502ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const StringValue* string_value =
503ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        static_cast<const StringValue*>(list_member);
504ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    std::string image_dest;
505ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    string_value->GetAsString(&image_dest);
506ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    image_target_ = FilePath(image_dest);
507ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
508ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    LOG(ERROR) << "Unable to get path string";
509ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
510ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
511ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
512ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::UnzipImage() {
513ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
514ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
515ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<ImageBurnTaskProxy> task = new ImageBurnTaskProxy(AsWeakPtr());
516ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BrowserThread::PostTask(
517ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        BrowserThread::FILE, FROM_HERE,
518ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        NewRunnableMethod(task.get(), &ImageBurnTaskProxy::UnzipImage));
519ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
520ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
521ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnHandler::UnzipImageOnFileThread(ImageBurnTaskProxy* task) {
522ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
523ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
524ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool success = UnzipImageImpl();
525ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BrowserThread::PostTask(
526ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        BrowserThread::UI, FROM_HERE,
527ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        NewRunnableMethod(task, &ImageBurnTaskProxy::UnzipComplete, success));
528ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
529ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
530ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ImageBurnHandler::UnzipImageImpl() {
531ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
532ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
533ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const FilePath& img_dir = resource_manager_->GetImageDir();
534ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!Unzip(zip_image_file_path_, img_dir))
535ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return false;
536ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
537ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  image_file_path_.clear();
538ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  file_util::FileEnumerator file_enumerator(
539ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      img_dir, false,  // recursive
540ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      file_util::FileEnumerator::FILES);
541ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (FilePath path = file_enumerator.Next();
542ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      !path.empty();
543ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen       path = file_enumerator.Next()) {
544ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (path != zip_image_file_path_) {
545ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      image_file_path_ = path;
546ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      break;
547ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
548ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
549ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return !image_file_path_.empty();
550ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
551ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
552ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen////////////////////////////////////////////////////////////////////////////////
553ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//
554ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// ImageBurnResourceManager
555ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//
556ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen////////////////////////////////////////////////////////////////////////////////
557ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
558ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenImageBurnResourceManager::ImageBurnResourceManager()
559ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    : image_download_requested_(false),
560ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      download_started_(false),
561ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      download_finished_(false),
562ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      burn_in_progress_(false),
563ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      download_manager_(NULL),
564ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      download_item_observer_added_(false),
565ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      active_download_item_(NULL),
566ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      image_url_(new GURL(kImageDownloadURL)),
567ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      config_file_url_(std::string(kImageBaseURL) + kImageFetcherName),
568ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      config_file_requested_(false),
569ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      config_file_fetched_(true) {
570ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  image_dir_.clear();
571ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
572ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
573ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenImageBurnResourceManager::~ImageBurnResourceManager() {
574ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!image_dir_.empty()) {
575ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    file_util::Delete(image_dir_, true);
576ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
577ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (active_download_item_)
578ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    active_download_item_->RemoveObserver(this);
579ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (download_manager_)
580ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    download_manager_->RemoveObserver(this);
581ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
582ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
583ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static
584ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenImageBurnResourceManager* ImageBurnResourceManager::GetInstance() {
585ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return Singleton<ImageBurnResourceManager>::get();
586ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
587ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
588ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnResourceManager::OnDownloadUpdated(DownloadItem* download) {
589ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (download->IsCancelled()) {
590ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    image_url_.reset();
591ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ConfigFileFetched(false);
592ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
593ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // ConfigFileFetched should remove observer.
594ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(!download_item_observer_added_);
595ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(active_download_item_ == NULL);
596ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else if (download->IsComplete()) {
597ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    std::string image_url;
598ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (file_util::ReadFileToString(config_file_path_, &image_url)) {
599ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      image_url_.reset(new GURL(std::string(kImageBaseURL) + image_url));
600ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ConfigFileFetched(true);
601ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
602ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      image_url_.reset();
603ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ConfigFileFetched(false);
604ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
605ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
606ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
607ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
608ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnResourceManager::ModelChanged() {
609ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<DownloadItem*> downloads;
610ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  download_manager_->GetTemporaryDownloads(GetImageDir(), &downloads);
611ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (download_item_observer_added_)
612ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
613ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (std::vector<DownloadItem*>::const_iterator it = downloads.begin();
614ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      it != downloads.end();
615ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ++it) {
616ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if ((*it)->url() == config_file_url_) {
617ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      download_item_observer_added_ = true;
618ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      (*it)->AddObserver(this);
619ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      active_download_item_ = *it;
620ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      break;
621ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
622ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
623ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
624ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
625ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnResourceManager::OnDownloadStarted(bool success) {
626ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!success)
627ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ConfigFileFetched(false);
628ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
629ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
630ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnResourceManager::CreateImageDir(
631ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    Delegate* delegate,
632ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ImageBurnTaskProxy* task) {
633ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
634ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
635ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool success = true;
636ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (image_dir_.empty()) {
637ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    CHECK(PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &image_dir_));
638ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    image_dir_ = image_dir_.Append(kTempImageFolderName);
639ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    success = file_util::CreateDirectory(image_dir_);
640ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
641ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delegate->OnImageDirCreated(success, task);
642ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
643ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
644ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst FilePath& ImageBurnResourceManager::GetImageDir() {
645ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return image_dir_;
646ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
647ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
648ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnResourceManager::SetDownloadFinished(bool finished) {
649ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!download_started_)
650ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
651ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!finished)
652ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    download_started_ = false;
653ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  download_finished_ = finished;
654ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
655ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
656ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnResourceManager::CreateImageUrl(TabContents* tab_contents,
657ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    Delegate* delegate) {
658ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (config_file_fetched_) {
659ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    delegate->OnImageUrlCreated(image_url_.get(), true);
660ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
661ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
662ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  downloaders_.push_back(delegate);
663ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
664ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (config_file_requested_)
665ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
666ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  config_file_requested_ = true;
667ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
668ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  config_file_path_ = GetImageDir().Append(kImageFetcherName);
669ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
670ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  download_manager_ = tab_contents->profile()->GetDownloadManager();
671ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  download_manager_->AddObserver(this);
672ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
673ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ImageBurnDownloader* downloader = ImageBurnDownloader::GetInstance();
674ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  downloader->AddListener(this, config_file_url_);
675ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  downloader->DownloadFile(config_file_url_, config_file_path_, tab_contents);
676ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
677ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
678ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnResourceManager::ConfigFileFetched(bool fetched) {
679ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (active_download_item_) {
680ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    active_download_item_->RemoveObserver(this);
681ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    active_download_item_ = NULL;
682ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
683ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  download_item_observer_added_ = false;
684ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (download_manager_)
685ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    download_manager_->RemoveObserver(this);
686ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!fetched)
687ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    config_file_requested_ = false;
688ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  config_file_fetched_ = fetched;
689ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (size_t i = 0; i < downloaders_.size(); ++i)
690ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    downloaders_[i]->OnImageUrlCreated(image_url_.get(), fetched);
691ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  downloaders_.clear();
692ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
693ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
694ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen////////////////////////////////////////////////////////////////////////////////
695ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//
696ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// ImageBurnDownloaderTaskProxy
697ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//
698ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen////////////////////////////////////////////////////////////////////////////////
699ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
700ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass ImageBurnDownloaderTaskProxy
701ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    : public base::RefCountedThreadSafe<ImageBurnDownloaderTaskProxy> {
702ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public:
703ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  explicit ImageBurnDownloaderTaskProxy() {}
704ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
705ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void CreateFileStream(const GURL& url,
706ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        const FilePath& target_path,
707ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        TabContents* tab_contents) {
708ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ImageBurnDownloader::GetInstance()->CreateFileStreamOnFileThread(url,
709ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        target_path, tab_contents, this);
710ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
711ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
712ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void OnFileStreamCreated(const GURL& url,
713ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                           const FilePath& file_path,
714ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                           TabContents* tab_contents,
715ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                           net::FileStream* created_file_stream) {
716ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ImageBurnDownloader::GetInstance()->OnFileStreamCreatedOnUIThread(url,
717ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        file_path, tab_contents, created_file_stream);
718ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
719ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
720ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen private:
721ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ~ImageBurnDownloaderTaskProxy() {}
722ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
723ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  friend class base::RefCountedThreadSafe<ImageBurnDownloaderTaskProxy>;
724ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
725ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DISALLOW_COPY_AND_ASSIGN(ImageBurnDownloaderTaskProxy);
726ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
727ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
728ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen////////////////////////////////////////////////////////////////////////////////
729ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//
730ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// ImageBurnDownloader
731ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//
732ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen////////////////////////////////////////////////////////////////////////////////
733ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
734ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static
735ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenImageBurnDownloader* ImageBurnDownloader::GetInstance() {
736ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return Singleton<ImageBurnDownloader>::get();
737ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
738ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
739ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnDownloader::DownloadFile(const GURL& url,
740ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const FilePath& file_path, TabContents* tab_contents) {
741ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // First we have to create file stream we will download file to.
742ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // That has to be done on File thread.
743ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<ImageBurnDownloaderTaskProxy> task =
744ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      new ImageBurnDownloaderTaskProxy();
745ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BrowserThread::PostTask(
746ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      BrowserThread::FILE, FROM_HERE,
747ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NewRunnableMethod(task.get(),
748ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          &ImageBurnDownloaderTaskProxy::CreateFileStream, url, file_path,
749ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          tab_contents));
750ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
751ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
752ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnDownloader::CreateFileStreamOnFileThread(
753ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const GURL& url, const FilePath& file_path,
754ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    TabContents* tab_contents, ImageBurnDownloaderTaskProxy* task) {
755ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
756ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
757ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(!file_path.empty());
758ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
759ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_ptr<net::FileStream> file_stream(new net::FileStream);
760ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (file_stream->Open(file_path, base::PLATFORM_FILE_CREATE_ALWAYS |
761ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        base::PLATFORM_FILE_WRITE))
762ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    file_stream.reset(NULL);
763ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
764ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Call callback method on UI thread.
765ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BrowserThread::PostTask(
766ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        BrowserThread::UI, FROM_HERE,
767ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        NewRunnableMethod(task,
768ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            &ImageBurnDownloaderTaskProxy::OnFileStreamCreated,
769ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            url, file_path, tab_contents, file_stream.release()));
770ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
771ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
772ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnDownloader::OnFileStreamCreatedOnUIThread(const GURL& url,
773ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const FilePath& file_path, TabContents* tab_contents,
774ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    net::FileStream* created_file_stream) {
775ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
776ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
777ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (created_file_stream) {
778ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DownloadManager* download_manager =
779ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        tab_contents->profile()->GetDownloadManager();
780ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DownloadSaveInfo save_info;
781ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    save_info.file_path = file_path;
782ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    save_info.file_stream = linked_ptr<net::FileStream>(created_file_stream);
783ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DownloadStarted(true, url);
784ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    download_manager->DownloadUrlToFile(url,
785ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                        tab_contents->GetURL(),
786ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                        tab_contents->encoding(),
787ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                        save_info,
788ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                        tab_contents);
789ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
790ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DownloadStarted(false, url);
791ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
792ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
793ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
794ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnDownloader::AddListener(Listener* listener, const GURL& url) {
795ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  listeners_.insert(std::make_pair(url, listener));
796ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
797ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
798ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ImageBurnDownloader::DownloadStarted(bool success, const GURL& url) {
799ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::pair<ListenerMap::iterator, ListenerMap::iterator> listener_range =
800ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      listeners_.equal_range(url);
801ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (ListenerMap::iterator current_listener = listener_range.first;
802ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen       current_listener != listener_range.second;
803ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen       ++current_listener) {
804ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    current_listener->second->OnDownloadStarted(success);
805ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
806ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  listeners_.erase(listener_range.first, listener_range.second);
807ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
808ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
809ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen////////////////////////////////////////////////////////////////////////////////
810ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//
811ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// ImageBurnUI
812ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//
813ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen////////////////////////////////////////////////////////////////////////////////
814ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenImageBurnUI::ImageBurnUI(TabContents* contents) : WebUI(contents) {
815ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ImageBurnHandler* handler = new ImageBurnHandler(contents);
816ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddMessageHandler((handler)->Attach(this));
817ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ImageBurnUIHTMLSource* html_source = new ImageBurnUIHTMLSource();
818ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source);
819ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
820