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

Side by Side Diff: extensions/utility/utility_handler.cc

Issue 2697463002: Convert utility process extension Unpacker IPC to mojo (Closed)
Patch Set: Use MakeUnique when creating the utility mojo client. Created 3 years, 10 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 "extensions/utility/utility_handler.h" 5 #include "extensions/utility/utility_handler.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/files/file_path.h" 8 #include "base/files/file_path.h"
9 #include "base/files/file_util.h"
10 #include "base/i18n/rtl.h"
11 #include "content/public/utility/utility_thread.h" 9 #include "content/public/utility/utility_thread.h"
12 #include "extensions/common/constants.h" 10 #include "extensions/common/constants.h"
13 #include "extensions/common/extension.h"
14 #include "extensions/common/extension_l10n_util.h" 11 #include "extensions/common/extension_l10n_util.h"
12 #include "extensions/common/extension_unpacker.mojom.h"
15 #include "extensions/common/extension_utility_messages.h" 13 #include "extensions/common/extension_utility_messages.h"
16 #include "extensions/common/extensions_client.h" 14 #include "extensions/common/extensions_client.h"
17 #include "extensions/common/manifest.h" 15 #include "extensions/common/manifest.h"
18 #include "extensions/common/update_manifest.h" 16 #include "extensions/common/update_manifest.h"
19 #include "extensions/strings/grit/extensions_strings.h" 17 #include "extensions/strings/grit/extensions_strings.h"
20 #include "extensions/utility/unpacker.h" 18 #include "extensions/utility/unpacker.h"
21 #include "ipc/ipc_message.h" 19 #include "ipc/ipc_message.h"
22 #include "ipc/ipc_message_macros.h" 20 #include "ipc/ipc_message_macros.h"
21 #include "mojo/public/cpp/bindings/strong_binding.h"
22 #include "services/service_manager/public/cpp/interface_registry.h"
23 #include "third_party/zlib/google/zip.h" 23 #include "third_party/zlib/google/zip.h"
24 #include "ui/base/l10n/l10n_util.h" 24 #include "ui/base/l10n/l10n_util.h"
25 #include "ui/base/ui_base_switches.h" 25 #include "ui/base/ui_base_switches.h"
26 26
27 namespace extensions { 27 namespace extensions {
28 28
29 namespace { 29 namespace {
30 30
31 bool Send(IPC::Message* message) { 31 class ExtensionUnpackerImpl : public extensions::mojom::ExtensionUnpacker {
32 return content::UtilityThread::Get()->Send(message); 32 public:
33 } 33 ExtensionUnpackerImpl() = default;
34 ~ExtensionUnpackerImpl() override = default;
34 35
35 void ReleaseProcessIfNeeded() { 36 static void Create(extensions::mojom::ExtensionUnpackerRequest request) {
36 content::UtilityThread::Get()->ReleaseProcessIfNeeded(); 37 mojo::MakeStrongBinding(base::MakeUnique<ExtensionUnpackerImpl>(),
37 } 38 std::move(request));
39 }
38 40
39 const char kExtensionHandlerUnzipError[] = 41 private:
40 "Could not unzip extension for install."; 42 // extensions::mojom::ExtensionUnpacker:
43 void Unzip(const base::FilePath& file,
44 const base::FilePath& path,
45 const UnzipCallback& callback) override {
46 if (auto manifest = UnzipFileManifest(file, path)) {
Devlin 2017/02/14 17:24:59 I think auto in this case reduces readability. Pl
Noel Gordon 2017/02/15 17:28:09 Ok removed the auto & put the code back the way it
47 callback.Run(UnzipFileIntoPath(file, path, std::move(manifest)));
48 } else {
49 callback.Run(false);
50 }
51 }
52
53 void Unpack(const base::FilePath& path,
54 const std::string& extension_id,
55 int32_t location,
56 int32_t creation_flags,
57 const UnpackCallback& callback) override {
58 CHECK_GT(location, Manifest::INVALID_LOCATION);
59 CHECK_LT(location, Manifest::NUM_LOCATIONS);
60 DCHECK(ExtensionsClient::Get());
61
62 content::UtilityThread::Get()->EnsureBlinkInitialized();
63
64 Unpacker unpacker(path.DirName(), path, extension_id,
65 static_cast<Manifest::Location>(location),
66 creation_flags);
67 if (unpacker.Run()) {
Devlin 2017/02/14 17:24:59 optional nit: presumably, unpacker.error_message()
Noel Gordon 2017/02/15 17:28:09 Dunno enough about unpacker to say, I was being co
68 callback.Run(base::string16(), unpacker.TakeParsedManifest());
69 } else {
70 callback.Run(unpacker.error_message(),
71 std::unique_ptr<base::DictionaryValue>());
72 }
73 }
74
75 static std::unique_ptr<base::DictionaryValue> UnzipFileManifest(
76 const base::FilePath& file,
77 const base::FilePath& path) {
78 if (zip::UnzipWithFilterCallback(
79 file, path, base::Bind(&Unpacker::IsManifestFile), false)) {
80 std::string error;
81 std::unique_ptr<base::DictionaryValue> manifest =
82 Unpacker::ReadManifest(path, &error);
83 return error.empty() && manifest ? std::move(manifest) : nullptr;
84 } else {
Devlin 2017/02/14 17:24:59 no else {} after return.
Noel Gordon 2017/02/15 17:28:09 Done.
85 return nullptr;
86 }
87 }
88
89 static bool UnzipFileIntoPath(
90 const base::FilePath& file,
91 const base::FilePath& path,
92 std::unique_ptr<base::DictionaryValue> manifest) {
93 Manifest internal(Manifest::INTERNAL, std::move(manifest));
94 // TODO(crbug.com/645263): This silently ignores blocked file types.
95 // Add install warnings.
96 return zip::UnzipWithFilterCallback(
97 file, path,
98 base::Bind(&Unpacker::ShouldExtractFile, internal.is_theme()),
99 true /* log_skipped_files */);
100 }
101
102 DISALLOW_COPY_AND_ASSIGN(ExtensionUnpackerImpl);
103 };
41 104
42 } // namespace 105 } // namespace
43 106
44 UtilityHandler::UtilityHandler() { 107 UtilityHandler::UtilityHandler() = default;
45 }
46 108
47 UtilityHandler::~UtilityHandler() { 109 UtilityHandler::~UtilityHandler() = default;
48 }
49 110
50 // static 111 // static
51 void UtilityHandler::UtilityThreadStarted() { 112 void UtilityHandler::UtilityThreadStarted() {
52 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 113 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
53 std::string lang = command_line->GetSwitchValueASCII(switches::kLang); 114 std::string lang = command_line->GetSwitchValueASCII(switches::kLang);
54 if (!lang.empty()) 115 if (!lang.empty())
55 extension_l10n_util::SetProcessLocale(lang); 116 extension_l10n_util::SetProcessLocale(lang);
56 } 117 }
57 118
119 // static
120 void UtilityHandler::ExposeInterfacesToBrowser(
121 service_manager::InterfaceRegistry* registry,
122 bool running_elevated) {
123 // If our process runs with elevated privileges, only add elevated Mojo
124 // services to the interface registry.
125 if (running_elevated)
126 return;
127
128 registry->AddInterface(base::Bind(&ExtensionUnpackerImpl::Create));
129 }
130
58 bool UtilityHandler::OnMessageReceived(const IPC::Message& message) { 131 bool UtilityHandler::OnMessageReceived(const IPC::Message& message) {
59 bool handled = true; 132 bool handled = true;
60 IPC_BEGIN_MESSAGE_MAP(UtilityHandler, message) 133 IPC_BEGIN_MESSAGE_MAP(UtilityHandler, message)
61 IPC_MESSAGE_HANDLER(ExtensionUtilityMsg_ParseUpdateManifest, 134 IPC_MESSAGE_HANDLER(ExtensionUtilityMsg_ParseUpdateManifest,
62 OnParseUpdateManifest) 135 OnParseUpdateManifest)
63 IPC_MESSAGE_HANDLER(ExtensionUtilityMsg_UnzipToDir, OnUnzipToDir)
64 IPC_MESSAGE_HANDLER(ExtensionUtilityMsg_UnpackExtension, OnUnpackExtension)
65 IPC_MESSAGE_UNHANDLED(handled = false) 136 IPC_MESSAGE_UNHANDLED(handled = false)
66 IPC_END_MESSAGE_MAP() 137 IPC_END_MESSAGE_MAP()
67 return handled; 138 return handled;
68 } 139 }
69 140
70 void UtilityHandler::OnParseUpdateManifest(const std::string& xml) { 141 void UtilityHandler::OnParseUpdateManifest(const std::string& xml) {
71 UpdateManifest manifest; 142 UpdateManifest manifest;
72 if (!manifest.Parse(xml)) { 143 if (!manifest.Parse(xml)) {
73 Send(new ExtensionUtilityHostMsg_ParseUpdateManifest_Failed( 144 content::UtilityThread::Get()->Send(
74 manifest.errors())); 145 new ExtensionUtilityHostMsg_ParseUpdateManifest_Failed(
146 manifest.errors()));
75 } else { 147 } else {
76 Send(new ExtensionUtilityHostMsg_ParseUpdateManifest_Succeeded( 148 content::UtilityThread::Get()->Send(
77 manifest.results())); 149 new ExtensionUtilityHostMsg_ParseUpdateManifest_Succeeded(
150 manifest.results()));
78 } 151 }
79 ReleaseProcessIfNeeded(); 152 content::UtilityThread::Get()->ReleaseProcessIfNeeded();
80 } 153 }
81 154
82 void UtilityHandler::OnUnzipToDir(const base::FilePath& zip_path,
83 const base::FilePath& dir) {
84 // First extract only the manifest to determine the extension type.
85 if (!zip::UnzipWithFilterCallback(zip_path, dir,
86 base::Bind(&Unpacker::IsManifestFile),
87 false /* log_skipped_files */)) {
88 Send(new ExtensionUtilityHostMsg_UnzipToDir_Failed(
89 std::string(kExtensionHandlerUnzipError)));
90 ReleaseProcessIfNeeded();
91 return;
92 }
93
94 // Load the manifest.
95 std::string error;
96 std::unique_ptr<base::DictionaryValue> dict =
97 Unpacker::ReadManifest(dir, &error);
98 if (!dict.get()) {
99 Send(new ExtensionUtilityHostMsg_UnzipToDir_Failed(
100 std::string(kExtensionHandlerUnzipError)));
101 ReleaseProcessIfNeeded();
102 return;
103 }
104
105 Manifest manifest(Manifest::INTERNAL, std::move(dict));
106 base::Callback<bool(const base::FilePath&)> filetype_filter_cb =
107 base::Bind(&Unpacker::ShouldExtractFile, manifest.is_theme());
108
109 // TODO(crbug.com/645263): This silently ignores blocked file types.
110 // Add install warnings.
111 if (!zip::UnzipWithFilterCallback(zip_path, dir, filetype_filter_cb,
112 true /* log_skipped_files */)) {
113 Send(new ExtensionUtilityHostMsg_UnzipToDir_Failed(
114 std::string(kExtensionHandlerUnzipError)));
115 } else {
116 Send(new ExtensionUtilityHostMsg_UnzipToDir_Succeeded(dir));
117 }
118 ReleaseProcessIfNeeded();
119 }
120
121 void UtilityHandler::OnUnpackExtension(const base::FilePath& directory_path,
122 const std::string& extension_id,
123 int location,
124 int creation_flags) {
125 CHECK_GT(location, Manifest::INVALID_LOCATION);
126 CHECK_LT(location, Manifest::NUM_LOCATIONS);
127 DCHECK(ExtensionsClient::Get());
128 content::UtilityThread::Get()->EnsureBlinkInitialized();
129 Unpacker unpacker(directory_path.DirName(), directory_path, extension_id,
130 static_cast<Manifest::Location>(location), creation_flags);
131 if (unpacker.Run()) {
132 Send(new ExtensionUtilityHostMsg_UnpackExtension_Succeeded(
133 *unpacker.parsed_manifest()));
134 } else {
135 Send(new ExtensionUtilityHostMsg_UnpackExtension_Failed(
136 unpacker.error_message()));
137 }
138 ReleaseProcessIfNeeded();
139 }
140
141
142 } // namespace extensions 155 } // namespace extensions
OLDNEW
« extensions/test/test_content_browser_client.cc ('K') | « extensions/utility/utility_handler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698