Switch global error menu icon to vectorized MD asset
[chromium-blink-merge.git] / chrome / browser / extensions / startup_helper.cc
blob53cd444db03a60fcf600eb5fc329a278c497f853
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.
5 #include "chrome/browser/extensions/startup_helper.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/command_line.h"
10 #include "base/files/file_path.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/run_loop.h"
13 #include "base/single_thread_task_runner.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "chrome/common/chrome_switches.h"
17 #include "chrome/common/extensions/chrome_extensions_client.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "extensions/browser/sandboxed_unpacker.h"
20 #include "extensions/common/extension.h"
22 using content::BrowserThread;
24 namespace extensions {
26 namespace {
28 void PrintPackExtensionMessage(const std::string& message) {
29 VLOG(1) << message;
32 } // namespace
34 StartupHelper::StartupHelper() : pack_job_succeeded_(false) {
35 ExtensionsClient::Set(ChromeExtensionsClient::GetInstance());
38 void StartupHelper::OnPackSuccess(
39 const base::FilePath& crx_path,
40 const base::FilePath& output_private_key_path) {
41 pack_job_succeeded_ = true;
42 PrintPackExtensionMessage(
43 base::UTF16ToUTF8(
44 PackExtensionJob::StandardSuccessMessage(crx_path,
45 output_private_key_path)));
48 void StartupHelper::OnPackFailure(const std::string& error_message,
49 ExtensionCreator::ErrorType type) {
50 PrintPackExtensionMessage(error_message);
53 bool StartupHelper::PackExtension(const base::CommandLine& cmd_line) {
54 if (!cmd_line.HasSwitch(switches::kPackExtension))
55 return false;
57 // Input Paths.
58 base::FilePath src_dir =
59 cmd_line.GetSwitchValuePath(switches::kPackExtension);
60 base::FilePath private_key_path;
61 if (cmd_line.HasSwitch(switches::kPackExtensionKey)) {
62 private_key_path = cmd_line.GetSwitchValuePath(switches::kPackExtensionKey);
65 // Launch a job to perform the packing on the file thread. Ignore warnings
66 // from the packing process. (e.g. Overwrite any existing crx file.)
67 pack_job_ = new PackExtensionJob(this, src_dir, private_key_path,
68 ExtensionCreator::kOverwriteCRX);
69 pack_job_->set_asynchronous(false);
70 pack_job_->Start();
72 return pack_job_succeeded_;
75 namespace {
77 class ValidateCrxHelper : public SandboxedUnpackerClient {
78 public:
79 ValidateCrxHelper(const CRXFileInfo& file,
80 const base::FilePath& temp_dir,
81 base::RunLoop* run_loop)
82 : crx_file_(file),
83 temp_dir_(temp_dir),
84 run_loop_(run_loop),
85 finished_(false),
86 success_(false) {}
88 bool finished() { return finished_; }
89 bool success() { return success_; }
90 const base::string16& error() { return error_; }
92 void Start() {
93 BrowserThread::PostTask(BrowserThread::FILE,
94 FROM_HERE,
95 base::Bind(&ValidateCrxHelper::StartOnFileThread,
96 this));
99 protected:
100 ~ValidateCrxHelper() override {}
102 void OnUnpackSuccess(const base::FilePath& temp_dir,
103 const base::FilePath& extension_root,
104 const base::DictionaryValue* original_manifest,
105 const Extension* extension,
106 const SkBitmap& install_icon) override {
107 finished_ = true;
108 success_ = true;
109 BrowserThread::PostTask(BrowserThread::UI,
110 FROM_HERE,
111 base::Bind(&ValidateCrxHelper::FinishOnUIThread,
112 this));
115 void OnUnpackFailure(const CrxInstallError& error) override {
116 finished_ = true;
117 success_ = false;
118 error_ = error.message();
119 BrowserThread::PostTask(BrowserThread::UI,
120 FROM_HERE,
121 base::Bind(&ValidateCrxHelper::FinishOnUIThread,
122 this));
125 void FinishOnUIThread() {
126 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
127 if (run_loop_->running())
128 run_loop_->Quit();
131 void StartOnFileThread() {
132 CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
133 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner =
134 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE);
136 scoped_refptr<SandboxedUnpacker> unpacker(new SandboxedUnpacker(
137 Manifest::INTERNAL, 0, /* no special creation flags */
138 temp_dir_, file_task_runner.get(), this));
139 unpacker->StartWithCrx(crx_file_);
142 // The file being validated.
143 const CRXFileInfo& crx_file_;
145 // The temporary directory where the sandboxed unpacker will do work.
146 const base::FilePath& temp_dir_;
148 // Unowned pointer to a runloop, so our consumer can wait for us to finish.
149 base::RunLoop* run_loop_;
151 // Whether we're finished unpacking;
152 bool finished_;
154 // Whether the unpacking was successful.
155 bool success_;
157 // If the unpacking wasn't successful, this contains an error message.
158 base::string16 error_;
161 } // namespace
163 bool StartupHelper::ValidateCrx(const base::CommandLine& cmd_line,
164 std::string* error) {
165 CHECK(error);
166 base::FilePath path = cmd_line.GetSwitchValuePath(switches::kValidateCrx);
167 if (path.empty()) {
168 *error = base::StringPrintf("Empty path passed for %s",
169 switches::kValidateCrx);
170 return false;
172 base::ScopedTempDir temp_dir;
174 if (!temp_dir.CreateUniqueTempDir()) {
175 *error = std::string("Failed to create temp dir");
176 return false;
179 base::RunLoop run_loop;
180 CRXFileInfo file(path);
181 scoped_refptr<ValidateCrxHelper> helper(
182 new ValidateCrxHelper(file, temp_dir.path(), &run_loop));
183 helper->Start();
184 if (!helper->finished())
185 run_loop.Run();
187 bool success = helper->success();
188 if (!success)
189 *error = base::UTF16ToUTF8(helper->error());
190 return success;
193 StartupHelper::~StartupHelper() {
194 if (pack_job_.get())
195 pack_job_->ClearClient();
198 } // namespace extensions