12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/input_method/component_extension_ime_manager_impl.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/file_util.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/component_loader.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_system.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/extensions/extension.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/extension_file_util.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/extension_l10n_util.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/extension_manifest_constants.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace chromeos { 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct WhitelistedComponentExtensionIME { 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* id; 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* path; 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} whitelisted_component_extension[] = { 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { 30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // ChromeOS Keyboards extension. 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "jhffeifommiaekmbkkjlpmilogcfdohp", 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "/usr/share/chromeos-assets/input_methods/keyboard_layouts", 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }, 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // ChromeOS Hangul Input. 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "bdgdidmhaijohebebipajioienkglgfo", 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "/usr/share/chromeos-assets/input_methods/hangul", 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }, 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OFFICIAL_BUILD) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Official Google Japanese Input. 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "fpfbhcjppmaeaijcidgiibchfbnhbelj", 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "/usr/share/chromeos-assets/input_methods/nacl_mozc", 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }, 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 464311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch // Google Chinese Input (zhuyin) 474311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch "goedamlknlnjaengojinmfgpmdjmkooo", 484311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch "/usr/share/chromeos-assets/input_methods/zhuyin", 494311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch }, 504311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch { 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Google Chinese Input (pinyin) 52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "nmblnjkfdkabgdofidlkienfnnbjhnab", 53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "/usr/share/chromeos-assets/input_methods/pinyin", 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) }, 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) { 56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Google Chinese Input (cangjie) 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "gjhclobljhjhgoebiipblnmdodbmpdgd", 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "/usr/share/chromeos-assets/input_methods/cangjie", 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) }, 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) { 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Google input tools. 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "gjaehgfemfahhmlgpdfknkhdnemmolop", 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "/usr/share/chromeos-assets/input_methods/input_tools", 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }, 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#else 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Open-sourced Pinyin Chinese Input Method. 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "cpgalbafkoofkjmaeonnfijgpfennjjn", 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "/usr/share/chromeos-assets/input_methods/pinyin", 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }, 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { 724311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch // Open-sourced Zhuyin Chinese Input Method. 734311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch "ekbifjdfhkmdeeajnolmgdlmkllopefi", 744311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch "/usr/share/chromeos-assets/input_methods/zhuyin", 754311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch }, 764311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch { 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Open-sourced Cangjie Chinese Input Method. 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "aeebooiibjahgpgmhkeocbeekccfknbj", 79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "/usr/share/chromeos-assets/input_methods/cangjie", 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }, 81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Open-sourced Mozc Japanese Input. 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "bbaiamgfapehflhememkfglaehiobjnk", 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "/usr/share/chromeos-assets/input_methods/nacl_mozc", 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }, 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extensions::ComponentLoader* GetComponentLoader() { 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord(); 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::ExtensionSystem* extension_system = 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::ExtensionSystem::Get(profile); 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionService* extension_service = extension_system->extension_service(); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return extension_service->component_loader(); 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ComponentExtensionIMEManagerImpl::ComponentExtensionIMEManagerImpl() 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : is_initialized_(false), 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_(this) { 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ComponentExtensionIMEManagerImpl::~ComponentExtensionIMEManagerImpl() { 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::vector<ComponentExtensionIME> ComponentExtensionIMEManagerImpl::ListIME() { 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return component_extension_list_; 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ComponentExtensionIMEManagerImpl::Load(const std::string& extension_id, 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& manifest, 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& file_path) { 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (loaded_extension_id_.find(extension_id) != loaded_extension_id_.end()) 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string loaded_extension_id = 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetComponentLoader()->Add(manifest, file_path); 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(loaded_extension_id, extension_id); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) loaded_extension_id_.insert(extension_id); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ComponentExtensionIMEManagerImpl::Unload(const std::string& extension_id, 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& file_path) { 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (loaded_extension_id_.find(extension_id) == loaded_extension_id_.end()) 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetComponentLoader()->Remove(extension_id); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) loaded_extension_id_.erase(extension_id); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<DictionaryValue> ComponentExtensionIMEManagerImpl::GetManifest( 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& file_path) { 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string error; 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<DictionaryValue> manifest( 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_file_util::LoadManifest(file_path, &error)); 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!manifest.get()) 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Failed at getting manifest"; 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!extension_l10n_util::LocalizeExtension(file_path, 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) manifest.get(), 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &error)) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Localization failed"; 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return manifest.Pass(); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ComponentExtensionIMEManagerImpl::InitializeAsync( 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Closure& callback) { 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!is_initialized_); 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<ComponentExtensionIME>* component_extension_ime_list 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) = new std::vector<ComponentExtensionIME>; 1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) content::BrowserThread::PostTaskAndReply( 1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) content::BrowserThread::FILE, 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&ComponentExtensionIMEManagerImpl::ReadComponentExtensionsInfo, 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(component_extension_ime_list)), 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind( 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &ComponentExtensionIMEManagerImpl::OnReadComponentExtensionsInfo, 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Owned(component_extension_ime_list), 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback)); 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ComponentExtensionIMEManagerImpl::IsInitialized() { 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return is_initialized_; 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ComponentExtensionIMEManagerImpl::ReadEngineComponent( 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DictionaryValue& dict, 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ComponentExtensionEngine* out) { 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(out); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string type; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!dict.GetString(extension_manifest_keys::kType, &type)) 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (type != "ime") 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!dict.GetString(extension_manifest_keys::kId, &out->engine_id)) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!dict.GetString(extension_manifest_keys::kName, &out->display_name)) 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 188a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 189a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch std::set<std::string> languages; 190a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const base::Value* language_value = NULL; 191a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if (dict.Get(extension_manifest_keys::kLanguage, &language_value)) { 192a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if (language_value->GetType() == base::Value::TYPE_STRING) { 193a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch std::string language_str; 194a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch language_value->GetAsString(&language_str); 195a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch languages.insert(language_str); 196a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch } else if (language_value->GetType() == base::Value::TYPE_LIST) { 197a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const base::ListValue* language_list = NULL; 198a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch language_value->GetAsList(&language_list); 199a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch for (size_t j = 0; j < language_list->GetSize(); ++j) { 200a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch std::string language_str; 201a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if (language_list->GetString(j, &language_str)) 202a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch languages.insert(language_str); 203a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch } 204a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch } 205a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch } 206a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch DCHECK(!languages.empty()); 207a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch out->language_codes.assign(languages.begin(), languages.end()); 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ListValue* layouts = NULL; 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!dict.GetList(extension_manifest_keys::kLayouts, &layouts)) 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < layouts->GetSize(); ++i) { 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string buffer; 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (layouts->GetString(i, &buffer)) 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) out->layouts.push_back(buffer); 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ComponentExtensionIMEManagerImpl::ReadExtensionInfo( 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DictionaryValue& manifest, 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& extension_id, 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ComponentExtensionIME* out) { 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!manifest.GetString(extension_manifest_keys::kDescription, 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &out->description)) 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string url_string; 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!manifest.GetString(extension_manifest_keys::kOptionsPage, &url_string)) 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; // It's okay to return true on no option page case. 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL url = extensions::Extension::GetResourceURL( 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extensions::Extension::GetBaseURLFromExtensionId(extension_id), 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) url_string); 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!url.is_valid()) 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 239a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) out->options_page_url = url; 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ComponentExtensionIMEManagerImpl::ReadComponentExtensionsInfo( 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<ComponentExtensionIME>* out_imes) { 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(out_imes); 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < arraysize(whitelisted_component_extension); ++i) { 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ComponentExtensionIME component_ime; 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) component_ime.path = base::FilePath( 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) whitelisted_component_extension[i].path); 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath manifest_path = 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) component_ime.path.Append("manifest.json"); 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!base::PathExists(component_ime.path) || 2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch !base::PathExists(manifest_path)) 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) continue; 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!file_util::ReadFileToString(manifest_path, &component_ime.manifest)) 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) continue; 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<DictionaryValue> manifest = GetManifest(component_ime.path); 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!manifest.get()) 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!ReadExtensionInfo(*manifest.get(), 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) whitelisted_component_extension[i].id, 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &component_ime)) 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) component_ime.id = whitelisted_component_extension[i].id; 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ListValue* component_list; 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!manifest->GetList(extension_manifest_keys::kInputComponents, 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &component_list)) 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < component_list->GetSize(); ++i) { 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DictionaryValue* dictionary; 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!component_list->GetDictionary(i, &dictionary)) 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ComponentExtensionEngine engine; 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReadEngineComponent(*dictionary, &engine); 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) component_ime.engines.push_back(engine); 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) out_imes->push_back(component_ime); 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ComponentExtensionIMEManagerImpl::OnReadComponentExtensionsInfo( 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<ComponentExtensionIME>* result, 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Closure& callback) { 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(result); 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) component_extension_list_ = *result; 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_initialized_ = true; 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(); 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace chromeos 302