Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / utility / extensions / extensions_handler.cc
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.
4
5 #include "chrome/utility/extensions/extensions_handler.h"
6
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"
26
27 #if defined(OS_WIN)
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)
32
33 #if defined(OS_MACOSX)
34 #include "chrome/utility/media_galleries/iphoto_library_parser.h"
35 #endif  // defined(OS_MACOSX)
36
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)
43
44 namespace extensions {
45
46 namespace {
47
48 bool Send(IPC::Message* message) {
49   return content::UtilityThread::Get()->Send(message);
50 }
51
52 void ReleaseProcessIfNeeded() {
53   content::UtilityThread::Get()->ReleaseProcessIfNeeded();
54 }
55
56 const char kExtensionHandlerUnzipError[] =
57     "Could not unzip extension for install.";
58
59 }  // namespace
60
61 ExtensionsHandler::ExtensionsHandler() {}
62
63 ExtensionsHandler::~ExtensionsHandler() {}
64
65 // static
66 void ExtensionsHandler::PreSandboxStartup() {
67   // Initialize libexif for image metadata parsing.
68   metadata::ImageMetadataExtractor::InitializeLibrary();
69
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);
75 }
76
77 void ExtensionsHandler::UtilityThreadStarted() {
78   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
79   std::string lang = command_line->GetSwitchValueASCII(switches::kLang);
80   if (!lang.empty())
81     extension_l10n_util::SetProcessLocale(lang);
82 }
83
84 bool ExtensionsHandler::OnMessageReceived(const IPC::Message& message) {
85   bool handled = true;
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)
94 #if defined(OS_WIN)
95     IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseITunesPrefXml,
96                         OnParseITunesPrefXml)
97 #endif  // defined(OS_WIN)
98
99 #if defined(OS_MACOSX)
100     IPC_MESSAGE_HANDLER(ChromeUtilityMsg_ParseIPhotoLibraryXmlFile,
101                         OnParseIPhotoLibraryXmlFile)
102 #endif  // defined(OS_MACOSX)
103
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)
112
113 #if defined(OS_WIN)
114     IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_GetAndEncryptWiFiCredentials,
115                         OnGetAndEncryptWiFiCredentials)
116 #endif  // defined(OS_WIN)
117
118     IPC_MESSAGE_UNHANDLED(handled = false)
119   IPC_END_MESSAGE_MAP()
120   return handled;
121 }
122
123 void ExtensionsHandler::OnUnpackExtension(
124     const base::FilePath& extension_path,
125     const std::string& extension_id,
126     int location,
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,
132                     extension_id,
133                     static_cast<Manifest::Location>(location),
134                     creation_flags);
135   if (unpacker.Run() && unpacker.DumpImagesToFile() &&
136       unpacker.DumpMessageCatalogsToFile()) {
137     Send(new ChromeUtilityHostMsg_UnpackExtension_Succeeded(
138         *unpacker.parsed_manifest()));
139   } else {
140     Send(new ChromeUtilityHostMsg_UnpackExtension_Failed(
141         unpacker.error_message()));
142   }
143
144   ReleaseProcessIfNeeded();
145 }
146
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)));
152   } else {
153     Send(new ChromeUtilityHostMsg_UnzipToDir_Succeeded(dir));
154   }
155
156   ReleaseProcessIfNeeded();
157 }
158
159 void ExtensionsHandler::OnParseUpdateManifest(const std::string& xml) {
160   UpdateManifest manifest;
161   if (!manifest.Parse(xml)) {
162     Send(new ChromeUtilityHostMsg_ParseUpdateManifest_Failed(
163         manifest.errors()));
164   } else {
165     Send(new ChromeUtilityHostMsg_ParseUpdateManifest_Succeeded(
166         manifest.results()));
167   }
168   ReleaseProcessIfNeeded();
169 }
170
171 void ExtensionsHandler::OnDecodeImageBase64(
172     const std::string& encoded_string) {
173   std::string decoded_string;
174
175   if (!base::Base64Decode(encoded_string, &decoded_string)) {
176     Send(new ChromeUtilityHostMsg_DecodeImage_Failed());
177     return;
178   }
179
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]);
183   }
184
185   ChromeContentUtilityClient::DecodeImage(decoded_vector);
186 }
187
188 void ExtensionsHandler::OnParseJSON(const std::string& json) {
189   int error_code;
190   std::string error;
191   base::Value* value = base::JSONReader::ReadAndReturnError(
192       json, base::JSON_PARSE_RFC, &error_code, &error);
193   if (value) {
194     base::ListValue wrapper;
195     wrapper.Append(value);
196     Send(new ChromeUtilityHostMsg_ParseJSON_Succeeded(wrapper));
197   } else {
198     Send(new ChromeUtilityHostMsg_ParseJSON_Failed(error));
199   }
200   ReleaseProcessIfNeeded();
201 }
202
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();
212 }
213
214 #if defined(OS_WIN)
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();
221 }
222 #endif  // defined(OS_WIN)
223
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();
232 }
233 #endif  // defined(OS_MACOSX)
234
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();
243 }
244
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);
252   files.date_file =
253       IPC::PlatformFileForTransitToFile(album_table_files.date_file);
254   files.filename_file =
255       IPC::PlatformFileForTransitToFile(album_table_files.filename_file);
256   files.name_file =
257       IPC::PlatformFileForTransitToFile(album_table_files.name_file);
258   files.token_file =
259       IPC::PlatformFileForTransitToFile(album_table_files.token_file);
260   files.uid_file =
261       IPC::PlatformFileForTransitToFile(album_table_files.uid_file);
262
263   picasa::PicasaAlbumTableReader reader(files.Pass());
264   bool parse_success = reader.Init();
265   Send(new ChromeUtilityHostMsg_ParsePicasaPMPDatabase_Finished(
266       parse_success,
267       reader.albums(),
268       reader.folders()));
269   ReleaseProcessIfNeeded();
270 }
271
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);
277
278   Send(new ChromeUtilityHostMsg_IndexPicasaAlbumsContents_Finished(
279       indexer.albums_images()));
280   ReleaseProcessIfNeeded();
281 }
282 #endif  // defined(OS_WIN) || defined(OS_MACOSX)
283
284 #if defined(OS_WIN)
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);
290
291   std::string key_data;
292   std::string error;
293   wifi_service->GetKeyFromSystem(network_guid, &key_data, &error);
294
295   std::vector<uint8> ciphertext;
296   bool success = error.empty() && !key_data.empty();
297   if (success) {
298     success = networking_private_crypto::EncryptByteString(
299         public_key, key_data, &ciphertext);
300   }
301
302   Send(new ChromeUtilityHostMsg_GotEncryptedWiFiCredentials(ciphertext,
303                                                             success));
304 }
305 #endif  // defined(OS_WIN)
306
307 }  // namespace extensions