• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/utility/chrome_content_utility_client.h"
6 
7 #include "base/base64.h"
8 #include "base/bind.h"
9 #include "base/command_line.h"
10 #include "base/files/file_path.h"
11 #include "base/json/json_reader.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/path_service.h"
14 #include "base/time/time.h"
15 #include "chrome/common/chrome_utility_messages.h"
16 #include "chrome/common/extensions/chrome_extensions_client.h"
17 #include "chrome/common/extensions/update_manifest.h"
18 #include "chrome/common/safe_browsing/zip_analyzer.h"
19 #include "chrome/utility/chrome_content_utility_ipc_whitelist.h"
20 #include "chrome/utility/extensions/unpacker.h"
21 #include "chrome/utility/image_writer/image_writer_handler.h"
22 #include "chrome/utility/profile_import_handler.h"
23 #include "chrome/utility/web_resource_unpacker.h"
24 #include "content/public/child/image_decoder_utils.h"
25 #include "content/public/common/content_paths.h"
26 #include "content/public/common/content_switches.h"
27 #include "content/public/utility/utility_thread.h"
28 #include "courgette/courgette.h"
29 #include "courgette/third_party/bsdiff.h"
30 #include "extensions/common/extension.h"
31 #include "extensions/common/extension_l10n_util.h"
32 #include "extensions/common/manifest.h"
33 #include "media/base/media.h"
34 #include "media/base/media_file_checker.h"
35 #include "third_party/skia/include/core/SkBitmap.h"
36 #include "third_party/zlib/google/zip.h"
37 #include "ui/base/ui_base_switches.h"
38 #include "ui/gfx/codec/jpeg_codec.h"
39 #include "ui/gfx/rect.h"
40 #include "ui/gfx/size.h"
41 
42 #if defined(OS_WIN)
43 #include "chrome/common/extensions/api/networking_private/networking_private_crypto.h"
44 #include "chrome/utility/media_galleries/itunes_pref_parser_win.h"
45 #include "components/wifi/wifi_service.h"
46 #endif  // defined(OS_WIN)
47 
48 #if defined(OS_MACOSX)
49 #include "chrome/utility/media_galleries/iphoto_library_parser.h"
50 #endif  // defined(OS_MACOSX)
51 
52 #if defined(OS_WIN) || defined(OS_MACOSX)
53 #include "chrome/utility/media_galleries/iapps_xml_utils.h"
54 #include "chrome/utility/media_galleries/itunes_library_parser.h"
55 #include "chrome/utility/media_galleries/picasa_album_table_reader.h"
56 #include "chrome/utility/media_galleries/picasa_albums_indexer.h"
57 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
58 
59 #if !defined(OS_ANDROID) && !defined(OS_IOS)
60 #include "chrome/common/media_galleries/metadata_types.h"
61 #include "chrome/utility/media_galleries/image_metadata_extractor.h"
62 #include "chrome/utility/media_galleries/ipc_data_source.h"
63 #include "chrome/utility/media_galleries/media_metadata_parser.h"
64 #endif  // !defined(OS_ANDROID) && !defined(OS_IOS)
65 
66 #if defined(ENABLE_FULL_PRINTING)
67 #include "chrome/utility/printing_handler.h"
68 #endif
69 
70 #if defined(ENABLE_MDNS)
71 #include "chrome/utility/local_discovery/service_discovery_message_handler.h"
72 #endif
73 
74 namespace {
75 
Send(IPC::Message * message)76 bool Send(IPC::Message* message) {
77   return content::UtilityThread::Get()->Send(message);
78 }
79 
ReleaseProcessIfNeeded()80 void ReleaseProcessIfNeeded() {
81   content::UtilityThread::Get()->ReleaseProcessIfNeeded();
82 }
83 
84 #if !defined(OS_ANDROID) && !defined(OS_IOS)
FinishParseMediaMetadata(metadata::MediaMetadataParser * parser,const extensions::api::media_galleries::MediaMetadata & metadata,const std::vector<metadata::AttachedImage> & attached_images)85 void FinishParseMediaMetadata(
86     metadata::MediaMetadataParser* parser,
87     const extensions::api::media_galleries::MediaMetadata& metadata,
88     const std::vector<metadata::AttachedImage>& attached_images) {
89   Send(new ChromeUtilityHostMsg_ParseMediaMetadata_Finished(
90       true, *metadata.ToValue(), attached_images));
91   ReleaseProcessIfNeeded();
92 }
93 #endif  // !defined(OS_ANDROID) && !defined(OS_IOS)
94 
95 }  // namespace
96 
ChromeContentUtilityClient()97 ChromeContentUtilityClient::ChromeContentUtilityClient()
98     : filter_messages_(false) {
99 #if !defined(OS_ANDROID)
100   handlers_.push_back(new ProfileImportHandler());
101 #endif
102 
103 #if defined(ENABLE_FULL_PRINTING)
104   handlers_.push_back(new PrintingHandler());
105 #endif
106 
107 #if defined(ENABLE_MDNS)
108   if (CommandLine::ForCurrentProcess()->HasSwitch(
109           switches::kUtilityProcessEnableMDns)) {
110     handlers_.push_back(new local_discovery::ServiceDiscoveryMessageHandler());
111   }
112 #endif
113 
114   handlers_.push_back(new image_writer::ImageWriterHandler());
115 }
116 
~ChromeContentUtilityClient()117 ChromeContentUtilityClient::~ChromeContentUtilityClient() {
118 }
119 
UtilityThreadStarted()120 void ChromeContentUtilityClient::UtilityThreadStarted() {
121   CommandLine* command_line = CommandLine::ForCurrentProcess();
122   std::string lang = command_line->GetSwitchValueASCII(switches::kLang);
123   if (!lang.empty())
124     extension_l10n_util::SetProcessLocale(lang);
125 
126   if (command_line->HasSwitch(switches::kUtilityProcessRunningElevated)) {
127     message_id_whitelist_.insert(kMessageWhitelist,
128                                  kMessageWhitelist + kMessageWhitelistSize);
129     filter_messages_ = true;
130   }
131 }
132 
OnMessageReceived(const IPC::Message & message)133 bool ChromeContentUtilityClient::OnMessageReceived(
134     const IPC::Message& message) {
135   if (filter_messages_ && !ContainsKey(message_id_whitelist_, message.type()))
136     return false;
137 
138   bool handled = true;
139   IPC_BEGIN_MESSAGE_MAP(ChromeContentUtilityClient, message)
140     IPC_MESSAGE_HANDLER(ChromeUtilityMsg_UnpackExtension, OnUnpackExtension)
141     IPC_MESSAGE_HANDLER(ChromeUtilityMsg_UnpackWebResource,
142                         OnUnpackWebResource)
143     IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseUpdateManifest,
144                         OnParseUpdateManifest)
145     IPC_MESSAGE_HANDLER(ChromeUtilityMsg_DecodeImage, OnDecodeImage)
146     IPC_MESSAGE_HANDLER(ChromeUtilityMsg_DecodeImageBase64, OnDecodeImageBase64)
147     IPC_MESSAGE_HANDLER(ChromeUtilityMsg_RobustJPEGDecodeImage,
148                         OnRobustJPEGDecodeImage)
149     IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseJSON, OnParseJSON)
150     IPC_MESSAGE_HANDLER(ChromeUtilityMsg_PatchFileBsdiff,
151                         OnPatchFileBsdiff)
152     IPC_MESSAGE_HANDLER(ChromeUtilityMsg_PatchFileCourgette,
153                         OnPatchFileCourgette)
154     IPC_MESSAGE_HANDLER(ChromeUtilityMsg_StartupPing, OnStartupPing)
155     IPC_MESSAGE_HANDLER(ChromeUtilityMsg_AnalyzeZipFileForDownloadProtection,
156                         OnAnalyzeZipFileForDownloadProtection)
157 
158 #if !defined(OS_ANDROID) && !defined(OS_IOS)
159     IPC_MESSAGE_HANDLER(ChromeUtilityMsg_CheckMediaFile, OnCheckMediaFile)
160     IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseMediaMetadata,
161                         OnParseMediaMetadata)
162 #endif  // !defined(OS_ANDROID) && !defined(OS_IOS)
163 
164 #if defined(OS_CHROMEOS)
165     IPC_MESSAGE_HANDLER(ChromeUtilityMsg_CreateZipFile, OnCreateZipFile)
166 #endif  // defined(OS_CHROMEOS)
167 
168 #if defined(OS_WIN)
169     IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseITunesPrefXml,
170                         OnParseITunesPrefXml)
171 #endif  // defined(OS_WIN)
172 
173 #if defined(OS_MACOSX)
174     IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseIPhotoLibraryXmlFile,
175                         OnParseIPhotoLibraryXmlFile)
176 #endif  // defined(OS_MACOSX)
177 
178 #if defined(OS_WIN) || defined(OS_MACOSX)
179     IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseITunesLibraryXmlFile,
180                         OnParseITunesLibraryXmlFile)
181     IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParsePicasaPMPDatabase,
182                         OnParsePicasaPMPDatabase)
183     IPC_MESSAGE_HANDLER(ChromeUtilityMsg_IndexPicasaAlbumsContents,
184                         OnIndexPicasaAlbumsContents)
185 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
186 
187 #if defined(OS_WIN)
188     IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_GetAndEncryptWiFiCredentials,
189                         OnGetAndEncryptWiFiCredentials)
190 #endif  // defined(OS_WIN)
191 
192     IPC_MESSAGE_UNHANDLED(handled = false)
193   IPC_END_MESSAGE_MAP()
194 
195   for (Handlers::iterator it = handlers_.begin();
196        !handled && it != handlers_.end(); ++it) {
197     handled = (*it)->OnMessageReceived(message);
198   }
199 
200   return handled;
201 }
202 
203 // static
PreSandboxStartup()204 void ChromeContentUtilityClient::PreSandboxStartup() {
205 #if defined(ENABLE_FULL_PRINTING)
206   PrintingHandler::PreSandboxStartup();
207 #endif
208 
209 #if defined(ENABLE_MDNS)
210   if (CommandLine::ForCurrentProcess()->HasSwitch(
211           switches::kUtilityProcessEnableMDns)) {
212     local_discovery::ServiceDiscoveryMessageHandler::PreSandboxStartup();
213   }
214 #endif  // ENABLE_MDNS
215 
216 #if !defined(OS_ANDROID) && !defined(OS_IOS)
217   // Initialize libexif for image metadata parsing.
218   metadata::ImageMetadataExtractor::InitializeLibrary();
219 #endif  // !defined(OS_ANDROID) && !defined(OS_IOS)
220 
221   // Load media libraries for media file validation.
222   base::FilePath media_path;
223   PathService::Get(content::DIR_MEDIA_LIBS, &media_path);
224   if (!media_path.empty())
225     media::InitializeMediaLibrary(media_path);
226 }
227 
OnUnpackExtension(const base::FilePath & extension_path,const std::string & extension_id,int location,int creation_flags)228 void ChromeContentUtilityClient::OnUnpackExtension(
229     const base::FilePath& extension_path,
230     const std::string& extension_id,
231     int location,
232     int creation_flags) {
233   CHECK_GT(location, extensions::Manifest::INVALID_LOCATION);
234   CHECK_LT(location, extensions::Manifest::NUM_LOCATIONS);
235   extensions::ExtensionsClient::Set(
236       extensions::ChromeExtensionsClient::GetInstance());
237   extensions::Unpacker unpacker(
238       extension_path,
239       extension_id,
240       static_cast<extensions::Manifest::Location>(location),
241       creation_flags);
242   if (unpacker.Run() && unpacker.DumpImagesToFile() &&
243       unpacker.DumpMessageCatalogsToFile()) {
244     Send(new ChromeUtilityHostMsg_UnpackExtension_Succeeded(
245         *unpacker.parsed_manifest()));
246   } else {
247     Send(new ChromeUtilityHostMsg_UnpackExtension_Failed(
248         unpacker.error_message()));
249   }
250 
251   ReleaseProcessIfNeeded();
252 }
253 
OnUnpackWebResource(const std::string & resource_data)254 void ChromeContentUtilityClient::OnUnpackWebResource(
255     const std::string& resource_data) {
256   // Parse json data.
257   // TODO(mrc): Add the possibility of a template that controls parsing, and
258   // the ability to download and verify images.
259   WebResourceUnpacker unpacker(resource_data);
260   if (unpacker.Run()) {
261     Send(new ChromeUtilityHostMsg_UnpackWebResource_Succeeded(
262         *unpacker.parsed_json()));
263   } else {
264     Send(new ChromeUtilityHostMsg_UnpackWebResource_Failed(
265         unpacker.error_message()));
266   }
267 
268   ReleaseProcessIfNeeded();
269 }
270 
OnParseUpdateManifest(const std::string & xml)271 void ChromeContentUtilityClient::OnParseUpdateManifest(const std::string& xml) {
272   UpdateManifest manifest;
273   if (!manifest.Parse(xml)) {
274     Send(new ChromeUtilityHostMsg_ParseUpdateManifest_Failed(
275         manifest.errors()));
276   } else {
277     Send(new ChromeUtilityHostMsg_ParseUpdateManifest_Succeeded(
278         manifest.results()));
279   }
280   ReleaseProcessIfNeeded();
281 }
282 
OnDecodeImage(const std::vector<unsigned char> & encoded_data)283 void ChromeContentUtilityClient::OnDecodeImage(
284     const std::vector<unsigned char>& encoded_data) {
285   const SkBitmap& decoded_image = content::DecodeImage(&encoded_data[0],
286                                                        gfx::Size(),
287                                                        encoded_data.size());
288   if (decoded_image.empty()) {
289     Send(new ChromeUtilityHostMsg_DecodeImage_Failed());
290   } else {
291     Send(new ChromeUtilityHostMsg_DecodeImage_Succeeded(decoded_image));
292   }
293   ReleaseProcessIfNeeded();
294 }
295 
OnDecodeImageBase64(const std::string & encoded_string)296 void ChromeContentUtilityClient::OnDecodeImageBase64(
297     const std::string& encoded_string) {
298   std::string decoded_string;
299 
300   if (!base::Base64Decode(encoded_string, &decoded_string)) {
301     Send(new ChromeUtilityHostMsg_DecodeImage_Failed());
302     return;
303   }
304 
305   std::vector<unsigned char> decoded_vector(decoded_string.size());
306   for (size_t i = 0; i < decoded_string.size(); ++i) {
307     decoded_vector[i] = static_cast<unsigned char>(decoded_string[i]);
308   }
309 
310   OnDecodeImage(decoded_vector);
311 }
312 
313 #if defined(OS_CHROMEOS)
OnCreateZipFile(const base::FilePath & src_dir,const std::vector<base::FilePath> & src_relative_paths,const base::FileDescriptor & dest_fd)314 void ChromeContentUtilityClient::OnCreateZipFile(
315     const base::FilePath& src_dir,
316     const std::vector<base::FilePath>& src_relative_paths,
317     const base::FileDescriptor& dest_fd) {
318   bool succeeded = true;
319 
320   // Check sanity of source relative paths. Reject if path is absolute or
321   // contains any attempt to reference a parent directory ("../" tricks).
322   for (std::vector<base::FilePath>::const_iterator iter =
323            src_relative_paths.begin(); iter != src_relative_paths.end();
324        ++iter) {
325     if (iter->IsAbsolute() || iter->ReferencesParent()) {
326       succeeded = false;
327       break;
328     }
329   }
330 
331   if (succeeded)
332     succeeded = zip::ZipFiles(src_dir, src_relative_paths, dest_fd.fd);
333 
334   if (succeeded)
335     Send(new ChromeUtilityHostMsg_CreateZipFile_Succeeded());
336   else
337     Send(new ChromeUtilityHostMsg_CreateZipFile_Failed());
338   ReleaseProcessIfNeeded();
339 }
340 #endif  // defined(OS_CHROMEOS)
341 
OnRobustJPEGDecodeImage(const std::vector<unsigned char> & encoded_data)342 void ChromeContentUtilityClient::OnRobustJPEGDecodeImage(
343     const std::vector<unsigned char>& encoded_data) {
344   // Our robust jpeg decoding is using IJG libjpeg.
345   if (gfx::JPEGCodec::JpegLibraryVariant() == gfx::JPEGCodec::IJG_LIBJPEG) {
346     scoped_ptr<SkBitmap> decoded_image(gfx::JPEGCodec::Decode(
347         &encoded_data[0], encoded_data.size()));
348     if (!decoded_image.get() || decoded_image->empty()) {
349       Send(new ChromeUtilityHostMsg_DecodeImage_Failed());
350     } else {
351       Send(new ChromeUtilityHostMsg_DecodeImage_Succeeded(*decoded_image));
352     }
353   } else {
354     Send(new ChromeUtilityHostMsg_DecodeImage_Failed());
355   }
356   ReleaseProcessIfNeeded();
357 }
358 
OnParseJSON(const std::string & json)359 void ChromeContentUtilityClient::OnParseJSON(const std::string& json) {
360   int error_code;
361   std::string error;
362   base::Value* value = base::JSONReader::ReadAndReturnError(
363       json, base::JSON_PARSE_RFC, &error_code, &error);
364   if (value) {
365     base::ListValue wrapper;
366     wrapper.Append(value);
367     Send(new ChromeUtilityHostMsg_ParseJSON_Succeeded(wrapper));
368   } else {
369     Send(new ChromeUtilityHostMsg_ParseJSON_Failed(error));
370   }
371   ReleaseProcessIfNeeded();
372 }
373 
OnPatchFileBsdiff(const base::FilePath & input_file,const base::FilePath & patch_file,const base::FilePath & output_file)374 void ChromeContentUtilityClient::OnPatchFileBsdiff(
375     const base::FilePath& input_file,
376     const base::FilePath& patch_file,
377     const base::FilePath& output_file) {
378   if (input_file.empty() || patch_file.empty() || output_file.empty()) {
379     Send(new ChromeUtilityHostMsg_PatchFile_Failed(-1));
380   } else {
381     const int patch_status = courgette::ApplyBinaryPatch(input_file,
382                                                          patch_file,
383                                                          output_file);
384     if (patch_status != courgette::OK)
385       Send(new ChromeUtilityHostMsg_PatchFile_Failed(patch_status));
386     else
387       Send(new ChromeUtilityHostMsg_PatchFile_Succeeded());
388   }
389   ReleaseProcessIfNeeded();
390 }
391 
OnPatchFileCourgette(const base::FilePath & input_file,const base::FilePath & patch_file,const base::FilePath & output_file)392 void ChromeContentUtilityClient::OnPatchFileCourgette(
393     const base::FilePath& input_file,
394     const base::FilePath& patch_file,
395     const base::FilePath& output_file) {
396   if (input_file.empty() || patch_file.empty() || output_file.empty()) {
397     Send(new ChromeUtilityHostMsg_PatchFile_Failed(-1));
398   } else {
399     const int patch_status = courgette::ApplyEnsemblePatch(
400         input_file.value().c_str(),
401         patch_file.value().c_str(),
402         output_file.value().c_str());
403     if (patch_status != courgette::C_OK)
404       Send(new ChromeUtilityHostMsg_PatchFile_Failed(patch_status));
405     else
406       Send(new ChromeUtilityHostMsg_PatchFile_Succeeded());
407   }
408   ReleaseProcessIfNeeded();
409 }
410 
OnStartupPing()411 void ChromeContentUtilityClient::OnStartupPing() {
412   Send(new ChromeUtilityHostMsg_ProcessStarted);
413   // Don't release the process, we assume further messages are on the way.
414 }
415 
OnAnalyzeZipFileForDownloadProtection(const IPC::PlatformFileForTransit & zip_file)416 void ChromeContentUtilityClient::OnAnalyzeZipFileForDownloadProtection(
417     const IPC::PlatformFileForTransit& zip_file) {
418   safe_browsing::zip_analyzer::Results results;
419   safe_browsing::zip_analyzer::AnalyzeZipFile(
420       IPC::PlatformFileForTransitToFile(zip_file), &results);
421   Send(new ChromeUtilityHostMsg_AnalyzeZipFileForDownloadProtection_Finished(
422       results));
423   ReleaseProcessIfNeeded();
424 }
425 
426 #if !defined(OS_ANDROID) && !defined(OS_IOS)
OnCheckMediaFile(int64 milliseconds_of_decoding,const IPC::PlatformFileForTransit & media_file)427 void ChromeContentUtilityClient::OnCheckMediaFile(
428     int64 milliseconds_of_decoding,
429     const IPC::PlatformFileForTransit& media_file) {
430   media::MediaFileChecker checker(
431       IPC::PlatformFileForTransitToFile(media_file));
432   const bool check_success = checker.Start(
433       base::TimeDelta::FromMilliseconds(milliseconds_of_decoding));
434   Send(new ChromeUtilityHostMsg_CheckMediaFile_Finished(check_success));
435   ReleaseProcessIfNeeded();
436 }
437 
OnParseMediaMetadata(const std::string & mime_type,int64 total_size,bool get_attached_images)438 void ChromeContentUtilityClient::OnParseMediaMetadata(
439     const std::string& mime_type, int64 total_size, bool get_attached_images) {
440   // Only one IPCDataSource may be created and added to the list of handlers.
441   metadata::IPCDataSource* source = new metadata::IPCDataSource(total_size);
442   handlers_.push_back(source);
443 
444   metadata::MediaMetadataParser* parser = new metadata::MediaMetadataParser(
445       source, mime_type, get_attached_images);
446   parser->Start(base::Bind(&FinishParseMediaMetadata, base::Owned(parser)));
447 }
448 #endif  // !defined(OS_ANDROID) && !defined(OS_IOS)
449 
450 #if defined(OS_WIN)
OnParseITunesPrefXml(const std::string & itunes_xml_data)451 void ChromeContentUtilityClient::OnParseITunesPrefXml(
452     const std::string& itunes_xml_data) {
453   base::FilePath library_path(
454       itunes::FindLibraryLocationInPrefXml(itunes_xml_data));
455   Send(new ChromeUtilityHostMsg_GotITunesDirectory(library_path));
456   ReleaseProcessIfNeeded();
457 }
458 #endif  // defined(OS_WIN)
459 
460 #if defined(OS_MACOSX)
OnParseIPhotoLibraryXmlFile(const IPC::PlatformFileForTransit & iphoto_library_file)461 void ChromeContentUtilityClient::OnParseIPhotoLibraryXmlFile(
462     const IPC::PlatformFileForTransit& iphoto_library_file) {
463   iphoto::IPhotoLibraryParser parser;
464   base::File file = IPC::PlatformFileForTransitToFile(iphoto_library_file);
465   bool result = parser.Parse(iapps::ReadFileAsString(file.Pass()));
466   Send(new ChromeUtilityHostMsg_GotIPhotoLibrary(result, parser.library()));
467   ReleaseProcessIfNeeded();
468 }
469 #endif  // defined(OS_MACOSX)
470 
471 #if defined(OS_WIN) || defined(OS_MACOSX)
OnParseITunesLibraryXmlFile(const IPC::PlatformFileForTransit & itunes_library_file)472 void ChromeContentUtilityClient::OnParseITunesLibraryXmlFile(
473     const IPC::PlatformFileForTransit& itunes_library_file) {
474   itunes::ITunesLibraryParser parser;
475   base::File file = IPC::PlatformFileForTransitToFile(itunes_library_file);
476   bool result = parser.Parse(iapps::ReadFileAsString(file.Pass()));
477   Send(new ChromeUtilityHostMsg_GotITunesLibrary(result, parser.library()));
478   ReleaseProcessIfNeeded();
479 }
480 
OnParsePicasaPMPDatabase(const picasa::AlbumTableFilesForTransit & album_table_files)481 void ChromeContentUtilityClient::OnParsePicasaPMPDatabase(
482     const picasa::AlbumTableFilesForTransit& album_table_files) {
483   picasa::AlbumTableFiles files;
484   files.indicator_file =
485       IPC::PlatformFileForTransitToFile(album_table_files.indicator_file);
486   files.category_file =
487       IPC::PlatformFileForTransitToFile(album_table_files.category_file);
488   files.date_file =
489       IPC::PlatformFileForTransitToFile(album_table_files.date_file);
490   files.filename_file =
491       IPC::PlatformFileForTransitToFile(album_table_files.filename_file);
492   files.name_file =
493       IPC::PlatformFileForTransitToFile(album_table_files.name_file);
494   files.token_file =
495       IPC::PlatformFileForTransitToFile(album_table_files.token_file);
496   files.uid_file =
497       IPC::PlatformFileForTransitToFile(album_table_files.uid_file);
498 
499   picasa::PicasaAlbumTableReader reader(files.Pass());
500   bool parse_success = reader.Init();
501   Send(new ChromeUtilityHostMsg_ParsePicasaPMPDatabase_Finished(
502       parse_success,
503       reader.albums(),
504       reader.folders()));
505   ReleaseProcessIfNeeded();
506 }
507 
OnIndexPicasaAlbumsContents(const picasa::AlbumUIDSet & album_uids,const std::vector<picasa::FolderINIContents> & folders_inis)508 void ChromeContentUtilityClient::OnIndexPicasaAlbumsContents(
509     const picasa::AlbumUIDSet& album_uids,
510     const std::vector<picasa::FolderINIContents>& folders_inis) {
511   picasa::PicasaAlbumsIndexer indexer(album_uids);
512   indexer.ParseFolderINI(folders_inis);
513 
514   Send(new ChromeUtilityHostMsg_IndexPicasaAlbumsContents_Finished(
515       indexer.albums_images()));
516   ReleaseProcessIfNeeded();
517 }
518 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
519 
520 #if defined(OS_WIN)
OnGetAndEncryptWiFiCredentials(const std::string & network_guid,const std::vector<uint8> & public_key)521 void ChromeContentUtilityClient::OnGetAndEncryptWiFiCredentials(
522     const std::string& network_guid,
523     const std::vector<uint8>& public_key) {
524   scoped_ptr<wifi::WiFiService> wifi_service(wifi::WiFiService::Create());
525   wifi_service->Initialize(NULL);
526 
527   std::string key_data;
528   std::string error;
529   wifi_service->GetKeyFromSystem(network_guid, &key_data, &error);
530 
531   std::vector<uint8> ciphertext;
532   bool success = error.empty() && !key_data.empty();
533   if (success) {
534     NetworkingPrivateCrypto crypto;
535     success = crypto.EncryptByteString(public_key, key_data, &ciphertext);
536   }
537 
538   Send(new ChromeUtilityHostMsg_GotEncryptedWiFiCredentials(ciphertext,
539                                                             success));
540 }
541 #endif  // defined(OS_WIN)
542