Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1758)

Side by Side Diff: chrome/browser/ui/webui/extensions/extension_loader_handler.cc

Issue 979453002: [Extensions] Make chrome://extensions use developerPrivate for unpacked loading (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comments Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/webui/extensions/extension_loader_handler.h" 5 #include "chrome/browser/ui/webui/extensions/extension_loader_handler.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/files/file_util.h" 8 #include "base/files/file_util.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/ref_counted.h" 10 #include "base/memory/ref_counted.h"
11 #include "base/strings/string16.h" 11 #include "base/strings/string16.h"
12 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
13 #include "base/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
14 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
15 #include "chrome/browser/extensions/path_util.h" 15 #include "chrome/browser/extensions/path_util.h"
16 #include "chrome/browser/extensions/unpacked_installer.h" 16 #include "chrome/browser/extensions/unpacked_installer.h"
17 #include "chrome/browser/extensions/zipfile_installer.h"
18 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/ui/chrome_select_file_policy.h"
20 #include "chrome/grit/generated_resources.h" 18 #include "chrome/grit/generated_resources.h"
21 #include "content/public/browser/browser_thread.h" 19 #include "content/public/browser/browser_thread.h"
22 #include "content/public/browser/user_metrics.h"
23 #include "content/public/browser/web_contents.h" 20 #include "content/public/browser/web_contents.h"
24 #include "content/public/browser/web_ui.h" 21 #include "content/public/browser/web_ui.h"
25 #include "content/public/browser/web_ui_data_source.h" 22 #include "content/public/browser/web_ui_data_source.h"
26 #include "extensions/browser/extension_system.h" 23 #include "extensions/browser/extension_system.h"
27 #include "extensions/browser/file_highlighter.h" 24 #include "extensions/browser/file_highlighter.h"
28 #include "extensions/common/constants.h" 25 #include "extensions/common/constants.h"
29 #include "extensions/common/extension.h" 26 #include "extensions/common/extension.h"
30 #include "extensions/common/manifest_constants.h" 27 #include "extensions/common/manifest_constants.h"
31 #include "third_party/re2/re2/re2.h" 28 #include "third_party/re2/re2/re2.h"
32 #include "ui/base/l10n/l10n_util.h" 29 #include "ui/base/l10n/l10n_util.h"
33 #include "ui/shell_dialogs/select_file_dialog.h"
34 30
35 namespace extensions { 31 namespace extensions {
36 32
37 namespace { 33 namespace {
38 34
39 // Read a file to a string and return. 35 // Read a file to a string and return.
40 std::string ReadFileToString(const base::FilePath& path) { 36 std::string ReadFileToString(const base::FilePath& path) {
41 std::string data; 37 std::string data;
42 // This call can fail, but it doesn't matter for our purposes. If it fails, 38 // This call can fail, but it doesn't matter for our purposes. If it fails,
43 // we simply return an empty string for the manifest, and ignore it. 39 // we simply return an empty string for the manifest, and ignore it.
44 base::ReadFileToString(path, &data); 40 base::ReadFileToString(path, &data);
45 return data; 41 return data;
46 } 42 }
47 43
48 } // namespace 44 } // namespace
49 45
50 class ExtensionLoaderHandler::FileHelper
51 : public ui::SelectFileDialog::Listener {
52 public:
53 explicit FileHelper(ExtensionLoaderHandler* loader_handler);
54 ~FileHelper() override;
55
56 // Create a FileDialog for the user to select the unpacked extension
57 // directory.
58 void ChooseFile();
59
60 private:
61 // ui::SelectFileDialog::Listener implementation.
62 void FileSelected(const base::FilePath& path,
63 int index,
64 void* params) override;
65 void MultiFilesSelected(const std::vector<base::FilePath>& files,
66 void* params) override;
67
68 // The associated ExtensionLoaderHandler. Weak, but guaranteed to be alive,
69 // as it owns this object.
70 ExtensionLoaderHandler* loader_handler_;
71
72 // The dialog used to pick a directory when loading an unpacked extension.
73 scoped_refptr<ui::SelectFileDialog> load_extension_dialog_;
74
75 // The last selected directory, so we can start in the same spot.
76 base::FilePath last_unpacked_directory_;
77
78 // The title of the dialog.
79 base::string16 title_;
80
81 DISALLOW_COPY_AND_ASSIGN(FileHelper);
82 };
83
84 ExtensionLoaderHandler::FileHelper::FileHelper(
85 ExtensionLoaderHandler* loader_handler)
86 : loader_handler_(loader_handler),
87 title_(l10n_util::GetStringUTF16(IDS_EXTENSION_LOAD_FROM_DIRECTORY)) {
88 }
89
90 ExtensionLoaderHandler::FileHelper::~FileHelper() {
91 // There may be a pending file dialog; inform it the listener is destroyed so
92 // it doesn't try and call back.
93 if (load_extension_dialog_.get())
94 load_extension_dialog_->ListenerDestroyed();
95 }
96
97 void ExtensionLoaderHandler::FileHelper::ChooseFile() {
98 static const int kFileTypeIndex = 0; // No file type information to index.
99 static const ui::SelectFileDialog::Type kSelectType =
100 ui::SelectFileDialog::SELECT_FOLDER;
101
102 gfx::NativeWindow parent_window =
103 loader_handler_->web_ui()->GetWebContents()->GetTopLevelNativeWindow();
104 if (!load_extension_dialog_.get()) {
105 load_extension_dialog_ = ui::SelectFileDialog::Create(
106 this,
107 new ChromeSelectFilePolicy(
108 loader_handler_->web_ui()->GetWebContents()));
109 } else if (load_extension_dialog_->IsRunning(parent_window)) {
110 // File chooser dialog is already running; ignore the click.
111 return;
112 }
113
114 load_extension_dialog_->SelectFile(
115 kSelectType,
116 title_,
117 last_unpacked_directory_,
118 NULL,
119 kFileTypeIndex,
120 base::FilePath::StringType(),
121 parent_window,
122 NULL);
123
124 content::RecordComputedAction("Options_LoadUnpackedExtension");
125 }
126
127 void ExtensionLoaderHandler::FileHelper::FileSelected(
128 const base::FilePath& path, int index, void* params) {
129 loader_handler_->LoadUnpackedExtensionImpl(path);
130 }
131
132 void ExtensionLoaderHandler::FileHelper::MultiFilesSelected(
133 const std::vector<base::FilePath>& files, void* params) {
134 NOTREACHED();
135 }
136
137 ExtensionLoaderHandler::ExtensionLoaderHandler(Profile* profile) 46 ExtensionLoaderHandler::ExtensionLoaderHandler(Profile* profile)
138 : profile_(profile), 47 : profile_(profile),
139 file_helper_(new FileHelper(this)),
140 extension_error_reporter_observer_(this), 48 extension_error_reporter_observer_(this),
141 ui_ready_(false), 49 ui_ready_(false),
142 weak_ptr_factory_(this) { 50 weak_ptr_factory_(this) {
143 DCHECK(profile_); 51 DCHECK(profile_);
144 extension_error_reporter_observer_.Add(ExtensionErrorReporter::GetInstance()); 52 extension_error_reporter_observer_.Add(ExtensionErrorReporter::GetInstance());
145 } 53 }
146 54
147 ExtensionLoaderHandler::~ExtensionLoaderHandler() { 55 ExtensionLoaderHandler::~ExtensionLoaderHandler() {
148 } 56 }
149 57
(...skipping 20 matching lines...) Expand all
170 } 78 }
171 79
172 void ExtensionLoaderHandler::RegisterMessages() { 80 void ExtensionLoaderHandler::RegisterMessages() {
173 // We observe WebContents in order to detect page refreshes, since notifying 81 // We observe WebContents in order to detect page refreshes, since notifying
174 // the frontend of load failures must be delayed until the page finishes 82 // the frontend of load failures must be delayed until the page finishes
175 // loading. We never call Observe(NULL) because this object is constructed 83 // loading. We never call Observe(NULL) because this object is constructed
176 // on page load and persists between refreshes. 84 // on page load and persists between refreshes.
177 content::WebContentsObserver::Observe(web_ui()->GetWebContents()); 85 content::WebContentsObserver::Observe(web_ui()->GetWebContents());
178 86
179 web_ui()->RegisterMessageCallback( 87 web_ui()->RegisterMessageCallback(
180 "extensionLoaderLoadUnpacked",
181 base::Bind(&ExtensionLoaderHandler::HandleLoadUnpacked,
182 weak_ptr_factory_.GetWeakPtr()));
183 web_ui()->RegisterMessageCallback(
184 "extensionLoaderRetry", 88 "extensionLoaderRetry",
185 base::Bind(&ExtensionLoaderHandler::HandleRetry, 89 base::Bind(&ExtensionLoaderHandler::HandleRetry,
186 weak_ptr_factory_.GetWeakPtr())); 90 weak_ptr_factory_.GetWeakPtr()));
187 web_ui()->RegisterMessageCallback( 91 web_ui()->RegisterMessageCallback(
188 "extensionLoaderIgnoreFailure", 92 "extensionLoaderIgnoreFailure",
189 base::Bind(&ExtensionLoaderHandler::HandleIgnoreFailure, 93 base::Bind(&ExtensionLoaderHandler::HandleIgnoreFailure,
190 weak_ptr_factory_.GetWeakPtr())); 94 weak_ptr_factory_.GetWeakPtr()));
191 web_ui()->RegisterMessageCallback( 95 web_ui()->RegisterMessageCallback(
192 "extensionLoaderDisplayFailures", 96 "extensionLoaderDisplayFailures",
193 base::Bind(&ExtensionLoaderHandler::HandleDisplayFailures, 97 base::Bind(&ExtensionLoaderHandler::HandleDisplayFailures,
194 weak_ptr_factory_.GetWeakPtr())); 98 weak_ptr_factory_.GetWeakPtr()));
195 } 99 }
196 100
197 void ExtensionLoaderHandler::HandleLoadUnpacked(const base::ListValue* args) {
198 DCHECK(args->empty());
199 file_helper_->ChooseFile();
200 }
201
202 void ExtensionLoaderHandler::HandleRetry(const base::ListValue* args) { 101 void ExtensionLoaderHandler::HandleRetry(const base::ListValue* args) {
203 DCHECK(args->empty()); 102 DCHECK(args->empty());
204 const base::FilePath file_path = failed_paths_.back(); 103 const base::FilePath file_path = failed_paths_.back();
205 failed_paths_.pop_back(); 104 failed_paths_.pop_back();
206 LoadUnpackedExtensionImpl(file_path); 105 LoadUnpackedExtension(file_path);
207 } 106 }
208 107
209 void ExtensionLoaderHandler::HandleIgnoreFailure(const base::ListValue* args) { 108 void ExtensionLoaderHandler::HandleIgnoreFailure(const base::ListValue* args) {
210 DCHECK(args->empty()); 109 DCHECK(args->empty());
211 failed_paths_.pop_back(); 110 failed_paths_.pop_back();
212 } 111 }
213 112
214 void ExtensionLoaderHandler::HandleDisplayFailures( 113 void ExtensionLoaderHandler::HandleDisplayFailures(
215 const base::ListValue* args) { 114 const base::ListValue* args) {
216 DCHECK(args->empty()); 115 DCHECK(args->empty());
217 ui_ready_ = true; 116 ui_ready_ = true;
218 117
219 // Notify the frontend of any load failures that were triggered while the 118 // Notify the frontend of any load failures that were triggered while the
220 // chrome://extensions page was loading. 119 // chrome://extensions page was loading.
221 if (!failures_.empty()) 120 if (!failures_.empty())
222 NotifyFrontendOfFailure(); 121 NotifyFrontendOfFailure();
223 } 122 }
224 123
225 void ExtensionLoaderHandler::LoadUnpackedExtensionImpl( 124 void ExtensionLoaderHandler::LoadUnpackedExtension(
226 const base::FilePath& file_path) { 125 const base::FilePath& file_path) {
227 scoped_refptr<UnpackedInstaller> installer = UnpackedInstaller::Create( 126 scoped_refptr<UnpackedInstaller> installer = UnpackedInstaller::Create(
228 ExtensionSystem::Get(profile_)->extension_service()); 127 ExtensionSystem::Get(profile_)->extension_service());
229 128
230 // We do our own error handling, so we don't want a load failure to trigger 129 // We do our own error handling, so we don't want a load failure to trigger
231 // a dialog. 130 // a dialog.
232 installer->set_be_noisy_on_failure(false); 131 installer->set_be_noisy_on_failure(false);
233 132
234 installer->Load(file_path); 133 installer->Load(file_path);
235 } 134 }
236 135
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 } 205 }
307 206
308 void ExtensionLoaderHandler::NotifyFrontendOfFailure() { 207 void ExtensionLoaderHandler::NotifyFrontendOfFailure() {
309 web_ui()->CallJavascriptFunction( 208 web_ui()->CallJavascriptFunction(
310 "extensions.ExtensionLoader.notifyLoadFailed", 209 "extensions.ExtensionLoader.notifyLoadFailed",
311 failures_); 210 failures_);
312 failures_.Clear(); 211 failures_.Clear();
313 } 212 }
314 213
315 } // namespace extensions 214 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/ui/webui/extensions/extension_loader_handler.h ('k') | chrome/common/extensions/api/developer_private.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698