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
3 // found in the LICENSE file.
5 #include "chrome/utility/extensions/extensions_handler.h"
7 #include "base/command_line.h"
8 #include "base/path_service.h"
9 #include "chrome/common/chrome_utility_messages.h"
10 #include "chrome/common/extensions/chrome_extensions_client.h"
11 #include "chrome/common/extensions/chrome_utility_extensions_messages.h"
12 #include "chrome/common/media_galleries/metadata_types.h"
13 #include "chrome/utility/chrome_content_utility_client.h"
14 #include "chrome/utility/extensions/unpacker.h"
15 #include "chrome/utility/media_galleries/image_metadata_extractor.h"
16 #include "content/public/common/content_paths.h"
17 #include "content/public/utility/utility_thread.h"
18 #include "extensions/common/extension.h"
19 #include "extensions/common/extension_l10n_util.h"
20 #include "extensions/common/manifest.h"
21 #include "extensions/common/update_manifest.h"
22 #include "media/base/media.h"
23 #include "media/base/media_file_checker.h"
24 #include "third_party/zlib/google/zip.h"
25 #include "ui/base/ui_base_switches.h"
28 #include "chrome/common/extensions/api/networking_private/networking_private_crypto.h"
29 #include "chrome/utility/media_galleries/itunes_pref_parser_win.h"
30 #include "components/wifi/wifi_service.h"
31 #endif // defined(OS_WIN)
33 #if defined(OS_MACOSX)
34 #include "chrome/utility/media_galleries/iphoto_library_parser.h"
35 #endif // defined(OS_MACOSX)
37 #if defined(OS_WIN) || defined(OS_MACOSX)
38 #include "chrome/utility/media_galleries/iapps_xml_utils.h"
39 #include "chrome/utility/media_galleries/itunes_library_parser.h"
40 #include "chrome/utility/media_galleries/picasa_album_table_reader.h"
41 #include "chrome/utility/media_galleries/picasa_albums_indexer.h"
42 #endif // defined(OS_WIN) || defined(OS_MACOSX)
44 namespace extensions
{
48 bool Send(IPC::Message
* message
) {
49 return content::UtilityThread::Get()->Send(message
);
52 void ReleaseProcessIfNeeded() {
53 content::UtilityThread::Get()->ReleaseProcessIfNeeded();
56 const char kExtensionHandlerUnzipError
[] =
57 "Could not unzip extension for install.";
61 ExtensionsHandler::ExtensionsHandler() {}
63 ExtensionsHandler::~ExtensionsHandler() {}
66 void ExtensionsHandler::PreSandboxStartup() {
67 // Initialize libexif for image metadata parsing.
68 metadata::ImageMetadataExtractor::InitializeLibrary();
70 // Load media libraries for media file validation.
71 base::FilePath media_path
;
72 PathService::Get(content::DIR_MEDIA_LIBS
, &media_path
);
73 if (!media_path
.empty())
74 media::InitializeMediaLibrary(media_path
);
77 void ExtensionsHandler::UtilityThreadStarted() {
78 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
79 std::string lang
= command_line
->GetSwitchValueASCII(switches::kLang
);
81 extension_l10n_util::SetProcessLocale(lang
);
84 bool ExtensionsHandler::OnMessageReceived(const IPC::Message
& message
) {
86 IPC_BEGIN_MESSAGE_MAP(ExtensionsHandler
, message
)
87 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_UnpackExtension
, OnUnpackExtension
)
88 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_UnzipToDir
, OnUnzipToDir
)
89 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseUpdateManifest
,
90 OnParseUpdateManifest
)
91 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_DecodeImageBase64
, OnDecodeImageBase64
)
92 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseJSON
, OnParseJSON
)
93 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_CheckMediaFile
, OnCheckMediaFile
)
95 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseITunesPrefXml
,
97 #endif // defined(OS_WIN)
99 #if defined(OS_MACOSX)
100 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseIPhotoLibraryXmlFile
,
101 OnParseIPhotoLibraryXmlFile
)
102 #endif // defined(OS_MACOSX)
104 #if defined(OS_WIN) || defined(OS_MACOSX)
105 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseITunesLibraryXmlFile
,
106 OnParseITunesLibraryXmlFile
)
107 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParsePicasaPMPDatabase
,
108 OnParsePicasaPMPDatabase
)
109 IPC_MESSAGE_HANDLER(ChromeUtilityMsg_IndexPicasaAlbumsContents
,
110 OnIndexPicasaAlbumsContents
)
111 #endif // defined(OS_WIN) || defined(OS_MACOSX)
114 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_GetAndEncryptWiFiCredentials
,
115 OnGetAndEncryptWiFiCredentials
)
116 #endif // defined(OS_WIN)
118 IPC_MESSAGE_UNHANDLED(handled
= false)
119 IPC_END_MESSAGE_MAP()
123 void ExtensionsHandler::OnUnpackExtension(
124 const base::FilePath
& extension_path
,
125 const std::string
& extension_id
,
127 int creation_flags
) {
128 CHECK_GT(location
, Manifest::INVALID_LOCATION
);
129 CHECK_LT(location
, Manifest::NUM_LOCATIONS
);
130 ExtensionsClient::Set(ChromeExtensionsClient::GetInstance());
131 Unpacker
unpacker(extension_path
,
133 static_cast<Manifest::Location
>(location
),
135 if (unpacker
.Run() && unpacker
.DumpImagesToFile() &&
136 unpacker
.DumpMessageCatalogsToFile()) {
137 Send(new ChromeUtilityHostMsg_UnpackExtension_Succeeded(
138 *unpacker
.parsed_manifest()));
140 Send(new ChromeUtilityHostMsg_UnpackExtension_Failed(
141 unpacker
.error_message()));
144 ReleaseProcessIfNeeded();
147 void ExtensionsHandler::OnUnzipToDir(const base::FilePath
& zip_path
,
148 const base::FilePath
& dir
) {
149 if (!zip::Unzip(zip_path
, dir
)) {
150 Send(new ChromeUtilityHostMsg_UnzipToDir_Failed(
151 std::string(kExtensionHandlerUnzipError
)));
153 Send(new ChromeUtilityHostMsg_UnzipToDir_Succeeded(dir
));
156 ReleaseProcessIfNeeded();
159 void ExtensionsHandler::OnParseUpdateManifest(const std::string
& xml
) {
160 UpdateManifest manifest
;
161 if (!manifest
.Parse(xml
)) {
162 Send(new ChromeUtilityHostMsg_ParseUpdateManifest_Failed(
165 Send(new ChromeUtilityHostMsg_ParseUpdateManifest_Succeeded(
166 manifest
.results()));
168 ReleaseProcessIfNeeded();
171 void ExtensionsHandler::OnDecodeImageBase64(
172 const std::string
& encoded_string
) {
173 std::string decoded_string
;
175 if (!base::Base64Decode(encoded_string
, &decoded_string
)) {
176 Send(new ChromeUtilityHostMsg_DecodeImage_Failed());
180 std::vector
<unsigned char> decoded_vector(decoded_string
.size());
181 for (size_t i
= 0; i
< decoded_string
.size(); ++i
) {
182 decoded_vector
[i
] = static_cast<unsigned char>(decoded_string
[i
]);
185 ChromeContentUtilityClient::DecodeImage(decoded_vector
);
188 void ExtensionsHandler::OnParseJSON(const std::string
& json
) {
191 base::Value
* value
= base::JSONReader::ReadAndReturnError(
192 json
, base::JSON_PARSE_RFC
, &error_code
, &error
);
194 base::ListValue wrapper
;
195 wrapper
.Append(value
);
196 Send(new ChromeUtilityHostMsg_ParseJSON_Succeeded(wrapper
));
198 Send(new ChromeUtilityHostMsg_ParseJSON_Failed(error
));
200 ReleaseProcessIfNeeded();
203 void ExtensionsHandler::OnCheckMediaFile(
204 int64 milliseconds_of_decoding
,
205 const IPC::PlatformFileForTransit
& media_file
) {
206 media::MediaFileChecker
checker(
207 IPC::PlatformFileForTransitToFile(media_file
));
208 const bool check_success
= checker
.Start(
209 base::TimeDelta::FromMilliseconds(milliseconds_of_decoding
));
210 Send(new ChromeUtilityHostMsg_CheckMediaFile_Finished(check_success
));
211 ReleaseProcessIfNeeded();
215 void ExtensionsHandler::OnParseITunesPrefXml(
216 const std::string
& itunes_xml_data
) {
217 base::FilePath
library_path(
218 itunes::FindLibraryLocationInPrefXml(itunes_xml_data
));
219 Send(new ChromeUtilityHostMsg_GotITunesDirectory(library_path
));
220 ReleaseProcessIfNeeded();
222 #endif // defined(OS_WIN)
224 #if defined(OS_MACOSX)
225 void ExtensionsHandler::OnParseIPhotoLibraryXmlFile(
226 const IPC::PlatformFileForTransit
& iphoto_library_file
) {
227 iphoto::IPhotoLibraryParser parser
;
228 base::File file
= IPC::PlatformFileForTransitToFile(iphoto_library_file
);
229 bool result
= parser
.Parse(iapps::ReadFileAsString(file
.Pass()));
230 Send(new ChromeUtilityHostMsg_GotIPhotoLibrary(result
, parser
.library()));
231 ReleaseProcessIfNeeded();
233 #endif // defined(OS_MACOSX)
235 #if defined(OS_WIN) || defined(OS_MACOSX)
236 void ExtensionsHandler::OnParseITunesLibraryXmlFile(
237 const IPC::PlatformFileForTransit
& itunes_library_file
) {
238 itunes::ITunesLibraryParser parser
;
239 base::File file
= IPC::PlatformFileForTransitToFile(itunes_library_file
);
240 bool result
= parser
.Parse(iapps::ReadFileAsString(file
.Pass()));
241 Send(new ChromeUtilityHostMsg_GotITunesLibrary(result
, parser
.library()));
242 ReleaseProcessIfNeeded();
245 void ExtensionsHandler::OnParsePicasaPMPDatabase(
246 const picasa::AlbumTableFilesForTransit
& album_table_files
) {
247 picasa::AlbumTableFiles files
;
248 files
.indicator_file
=
249 IPC::PlatformFileForTransitToFile(album_table_files
.indicator_file
);
250 files
.category_file
=
251 IPC::PlatformFileForTransitToFile(album_table_files
.category_file
);
253 IPC::PlatformFileForTransitToFile(album_table_files
.date_file
);
254 files
.filename_file
=
255 IPC::PlatformFileForTransitToFile(album_table_files
.filename_file
);
257 IPC::PlatformFileForTransitToFile(album_table_files
.name_file
);
259 IPC::PlatformFileForTransitToFile(album_table_files
.token_file
);
261 IPC::PlatformFileForTransitToFile(album_table_files
.uid_file
);
263 picasa::PicasaAlbumTableReader
reader(files
.Pass());
264 bool parse_success
= reader
.Init();
265 Send(new ChromeUtilityHostMsg_ParsePicasaPMPDatabase_Finished(
269 ReleaseProcessIfNeeded();
272 void ExtensionsHandler::OnIndexPicasaAlbumsContents(
273 const picasa::AlbumUIDSet
& album_uids
,
274 const std::vector
<picasa::FolderINIContents
>& folders_inis
) {
275 picasa::PicasaAlbumsIndexer
indexer(album_uids
);
276 indexer
.ParseFolderINI(folders_inis
);
278 Send(new ChromeUtilityHostMsg_IndexPicasaAlbumsContents_Finished(
279 indexer
.albums_images()));
280 ReleaseProcessIfNeeded();
282 #endif // defined(OS_WIN) || defined(OS_MACOSX)
285 void ExtensionsHandler::OnGetAndEncryptWiFiCredentials(
286 const std::string
& network_guid
,
287 const std::vector
<uint8
>& public_key
) {
288 scoped_ptr
<wifi::WiFiService
> wifi_service(wifi::WiFiService::Create());
289 wifi_service
->Initialize(NULL
);
291 std::string key_data
;
293 wifi_service
->GetKeyFromSystem(network_guid
, &key_data
, &error
);
295 std::vector
<uint8
> ciphertext
;
296 bool success
= error
.empty() && !key_data
.empty();
298 success
= networking_private_crypto::EncryptByteString(
299 public_key
, key_data
, &ciphertext
);
302 Send(new ChromeUtilityHostMsg_GotEncryptedWiFiCredentials(ciphertext
,
305 #endif // defined(OS_WIN)
307 } // namespace extensions