1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/extensions/pack_extension_job.h"
6
7#include "base/bind.h"
8#include "base/message_loop/message_loop.h"
9#include "base/strings/sys_string_conversions.h"
10#include "base/strings/utf_string_conversions.h"
11#include "chrome/browser/extensions/extension_creator.h"
12#include "chrome/grit/generated_resources.h"
13#include "extensions/common/constants.h"
14#include "ui/base/l10n/l10n_util.h"
15
16using content::BrowserThread;
17
18namespace extensions {
19
20PackExtensionJob::PackExtensionJob(Client* client,
21                                   const base::FilePath& root_directory,
22                                   const base::FilePath& key_file,
23                                   int run_flags)
24    : client_(client), key_file_(key_file), asynchronous_(true),
25      run_flags_(run_flags | ExtensionCreator::kRequireModernManifestVersion) {
26  root_directory_ = root_directory.StripTrailingSeparators();
27  CHECK(BrowserThread::GetCurrentThreadIdentifier(&client_thread_id_));
28}
29
30void PackExtensionJob::Start() {
31  if (asynchronous_) {
32    BrowserThread::PostTask(
33        BrowserThread::FILE, FROM_HERE,
34        base::Bind(&PackExtensionJob::Run, this));
35  } else {
36    Run();
37  }
38}
39
40void PackExtensionJob::ClearClient() {
41  client_ = NULL;
42}
43
44PackExtensionJob::~PackExtensionJob() {}
45
46void PackExtensionJob::Run() {
47  crx_file_out_ = base::FilePath(root_directory_.value() +
48                                 kExtensionFileExtension);
49
50  if (key_file_.empty())
51    key_file_out_ = base::FilePath(root_directory_.value() +
52                                   kExtensionKeyFileExtension);
53
54  // TODO(aa): Need to internationalize the errors that ExtensionCreator
55  // returns. See bug 20734.
56  ExtensionCreator creator;
57  if (creator.Run(root_directory_, crx_file_out_, key_file_, key_file_out_,
58                  run_flags_)) {
59    if (asynchronous_) {
60      BrowserThread::PostTask(
61          client_thread_id_, FROM_HERE,
62          base::Bind(&PackExtensionJob::ReportSuccessOnClientThread, this));
63    } else {
64      ReportSuccessOnClientThread();
65    }
66  } else {
67    if (asynchronous_) {
68      BrowserThread::PostTask(
69          client_thread_id_, FROM_HERE,
70          base::Bind(
71              &PackExtensionJob::ReportFailureOnClientThread, this,
72              creator.error_message(), creator.error_type()));
73    } else {
74      ReportFailureOnClientThread(creator.error_message(),
75          creator.error_type());
76    }
77  }
78}
79
80void PackExtensionJob::ReportSuccessOnClientThread() {
81  if (client_)
82    client_->OnPackSuccess(crx_file_out_, key_file_out_);
83}
84
85void PackExtensionJob::ReportFailureOnClientThread(
86    const std::string& error,
87    ExtensionCreator::ErrorType error_type) {
88  if (client_)
89    client_->OnPackFailure(error, error_type);
90}
91
92// static
93base::string16 PackExtensionJob::StandardSuccessMessage(
94    const base::FilePath& crx_file,
95    const base::FilePath& key_file) {
96  base::string16 crx_file_string = crx_file.LossyDisplayName();
97  base::string16 key_file_string = key_file.LossyDisplayName();
98  if (key_file_string.empty()) {
99    return l10n_util::GetStringFUTF16(
100        IDS_EXTENSION_PACK_DIALOG_SUCCESS_BODY_UPDATE,
101        crx_file_string);
102  } else {
103    return l10n_util::GetStringFUTF16(
104        IDS_EXTENSION_PACK_DIALOG_SUCCESS_BODY_NEW,
105        crx_file_string,
106        key_file_string);
107  }
108}
109
110}  // namespace extensions
111