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/app_mode/kiosk_app_data.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/file_util.h" 1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/json/json_writer.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/ref_counted_memory.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/prefs/scoped_user_pref_update.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/sequenced_worker_pool.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/browser_process.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/app_mode/kiosk_app_data_delegate.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" 2081843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 2181843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)#include "chrome/browser/extensions/extension_system.h" 2281843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)#include "chrome/browser/extensions/image_loader.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/webstore_data_fetcher.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/webstore_install_helper.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/image_decoder.h" 2681843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/extension_constants.h" 2881843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)#include "chrome/common/extensions/manifest_handlers/icons_handler.h" 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/manifest.h" 313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/manifest_constants.h" 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/codec/png_codec.h" 3381843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)#include "ui/gfx/image/image.h" 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::BrowserThread; 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace chromeos { 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Keys for local state data. See sample layout in KioskAppManager. 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kKeyName[] = "name"; 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kKeyIcon[] = "icon"; 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Web store data keys. 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kManifestKey[] = "manifest"; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kIconUrlKey[] = "icon_url"; 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kLocalizedNameKey[] = "localized_name"; 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kInvalidWebstoreResponseError[] = "Invalid Chrome Web Store reponse"; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Icon file extension. 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kIconFileExtension[] = ".png"; 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Save |raw_icon| for given |app_id|. 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SaveIconToLocalOnBlockingPool( 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& icon_path, 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::RefCountedString> raw_icon) { 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath dir = icon_path.DirName(); 627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!base::PathExists(dir)) 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CHECK(base::CreateDirectory(dir)); 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK_EQ(static_cast<int>(raw_icon->size()), 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_util::WriteFile(icon_path, 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raw_icon->data().c_str(), raw_icon->size())); 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Returns true for valid kiosk app manifest. 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool IsValidKioskAppManifest(const extensions::Manifest& manifest) { 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool kiosk_enabled; 733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (manifest.GetBoolean(extensions::manifest_keys::kKioskEnabled, 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &kiosk_enabled)) { 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return kiosk_enabled; 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)std::string ValueToString(const base::Value* value) { 8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string json; 8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::JSONWriter::Write(value, &json); 8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return json; 8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// KioskAppData::IconLoader 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Loads locally stored icon data and decode it. 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class KioskAppData::IconLoader : public ImageDecoder::Delegate { 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) enum LoadResult { 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SUCCESS, 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FAILED_TO_LOAD, 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FAILED_TO_DECODE, 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IconLoader(const base::WeakPtr<KioskAppData>& client, 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& icon_path) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : client_(client), 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_path_(icon_path), 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) load_result_(SUCCESS) {} 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Start() { 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool(); 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::SequencedWorkerPool::SequenceToken token = pool->GetSequenceToken(); 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task_runner_ = pool->GetSequencedTaskRunnerWithShutdownBehavior( 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) token, 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task_runner_->PostTask(FROM_HERE, 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&IconLoader::LoadOnBlockingPool, 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) friend class base::RefCountedThreadSafe<IconLoader>; 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~IconLoader() {} 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Loads the icon from locally stored |icon_path_| on the blocking pool 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void LoadOnBlockingPool() { 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(task_runner_->RunsTasksOnCurrentThread()); 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string data; 12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!base::ReadFileToString(base::FilePath(icon_path_), &data)) { 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReportResultOnBlockingPool(FAILED_TO_LOAD); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raw_icon_ = base::RefCountedString::TakeString(&data); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<ImageDecoder> image_decoder = new ImageDecoder( 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, raw_icon_->data(), ImageDecoder::DEFAULT_CODEC); 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) image_decoder->Start(task_runner_); 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void ReportResultOnBlockingPool(LoadResult result) { 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(task_runner_->RunsTasksOnCurrentThread()); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) load_result_ = result; 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask( 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::UI, 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&IconLoader::ReportResultOnUIThread, 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void NotifyClient() { 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!client_) 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (load_result_ == SUCCESS) 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_->OnIconLoadSuccess(raw_icon_, icon_); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_->OnIconLoadFailure(); 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void ReportResultOnUIThread() { 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyClient(); 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete this; 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ImageDecoder::Delegate overrides: 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnImageDecoded(const ImageDecoder* decoder, 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SkBitmap& decoded_image) OVERRIDE { 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_ = gfx::ImageSkia::CreateFrom1xBitmap(decoded_image); 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_.MakeThreadSafe(); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReportResultOnBlockingPool(SUCCESS); 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnDecodeImageFailed(const ImageDecoder* decoder) OVERRIDE { 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReportResultOnBlockingPool(FAILED_TO_DECODE); 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtr<KioskAppData> client_; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath icon_path_; 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LoadResult load_result_; 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> task_runner_; 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::ImageSkia icon_; 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::RefCountedString> raw_icon_; 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(IconLoader); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// KioskAppData::WebstoreDataParser 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use WebstoreInstallHelper to parse the manifest and decode the icon. 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class KioskAppData::WebstoreDataParser 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public extensions::WebstoreInstallHelper::Delegate { 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit WebstoreDataParser(const base::WeakPtr<KioskAppData>& client) 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : client_(client) {} 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Start(const std::string& app_id, 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& manifest, 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& icon_url, 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::URLRequestContextGetter* context_getter) { 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<extensions::WebstoreInstallHelper> webstore_helper = 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new extensions::WebstoreInstallHelper(this, 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app_id, 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) manifest, 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "", // No icon data. 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_url, 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context_getter); 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webstore_helper->Start(); 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) friend class base::RefCounted<WebstoreDataParser>; 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~WebstoreDataParser() {} 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void ReportFailure() { 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (client_) 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_->OnWebstoreParseFailure(); 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delete this; 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // WebstoreInstallHelper::Delegate overrides: 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnWebstoreParseSuccess( 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& id, 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SkBitmap& icon, 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* parsed_manifest) OVERRIDE { 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Takes ownership of |parsed_manifest|. 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extensions::Manifest manifest( 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extensions::Manifest::INVALID_LOCATION, 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::DictionaryValue>(parsed_manifest)); 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!IsValidKioskAppManifest(manifest)) { 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ReportFailure(); 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (client_) 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_->OnWebstoreParseSuccess(icon); 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete this; 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnWebstoreParseFailure( 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& id, 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InstallHelperResultCode result_code, 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& error_message) OVERRIDE { 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ReportFailure(); 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtr<KioskAppData> client_; 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(WebstoreDataParser); 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// KioskAppData 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)KioskAppData::KioskAppData(KioskAppDataDelegate* delegate, 26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& app_id, 26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& user_id) 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : delegate_(delegate), 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) status_(STATUS_INIT), 26690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) app_id_(app_id), 26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) user_id_(user_id) { 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)KioskAppData::~KioskAppData() {} 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppData::Load() { 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetStatus(STATUS_LOADING); 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (LoadFromCache()) 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartFetch(); 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppData::ClearCache() { 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PrefService* local_state = g_browser_process->local_state(); 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DictionaryPrefUpdate dict_update(local_state, 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KioskAppManager::kKioskDictionaryName); 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string app_key = std::string(KioskAppManager::kKeyApps) + '.' + app_id_; 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dict_update->Remove(app_key, NULL); 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!icon_path_.empty()) { 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostBlockingPoolTask( 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 2937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(base::IgnoreResult(&base::DeleteFile), icon_path_, false)); 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 29781843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)void KioskAppData::LoadFromInstalledApp(Profile* profile, 29881843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) const extensions::Extension* app) { 29981843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) SetStatus(STATUS_LOADING); 30081843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) 30181843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) if (!app) { 30281843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) app = extensions::ExtensionSystem::Get(profile) 30381843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) ->extension_service() 30481843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) ->GetInstalledExtension(app_id_); 30581843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) } 30681843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) 30781843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) DCHECK_EQ(app_id_, app->id()); 30881843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) 30981843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) name_ = app->name(); 31081843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) 31181843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) const int kIconSize = extension_misc::EXTENSION_ICON_LARGE; 31281843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) extensions::ExtensionResource image = extensions::IconsInfo::GetIconResource( 31381843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) app, kIconSize, ExtensionIconSet::MATCH_BIGGER); 31481843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) extensions::ImageLoader::Get(profile)->LoadImageAsync( 31581843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) app, image, gfx::Size(kIconSize, kIconSize), 31681843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) base::Bind(&KioskAppData::OnExtensionIconLoaded, AsWeakPtr())); 31781843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)} 31881843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool KioskAppData::IsLoading() const { 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status_ == STATUS_LOADING; 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppData::SetStatus(Status status) { 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status_ == status) 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) status_ = status; 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!delegate_) 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (status_) { 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case STATUS_INIT: 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case STATUS_LOADING: 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case STATUS_LOADED: 33790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delegate_->OnKioskAppDataChanged(app_id_); 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case STATUS_ERROR: 34090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delegate_->OnKioskAppDataLoadFailure(app_id_); 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)net::URLRequestContextGetter* KioskAppData::GetRequestContextGetter() { 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return g_browser_process->system_request_context(); 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool KioskAppData::LoadFromCache() { 35090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string app_key = std::string(KioskAppManager::kKeyApps) + '.' + app_id_; 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string name_key = app_key + '.' + kKeyName; 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string icon_path_key = app_key + '.' + kKeyIcon; 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PrefService* local_state = g_browser_process->local_state(); 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue* dict = 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_state->GetDictionary(KioskAppManager::kKioskDictionaryName); 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_path_.clear(); 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string icon_path_string; 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!dict->GetString(name_key, &name_) || 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !dict->GetString(icon_path_key, &icon_path_string)) { 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_path_ = base::FilePath(icon_path_string); 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // IconLoader deletes itself when done. 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (new IconLoader(AsWeakPtr(), icon_path_))->Start(); 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppData::SetCache(const std::string& name, 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& icon_path) { 37390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string app_key = std::string(KioskAppManager::kKeyApps) + '.' + app_id_; 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string name_key = app_key + '.' + kKeyName; 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string icon_path_key = app_key + '.' + kKeyIcon; 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PrefService* local_state = g_browser_process->local_state(); 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DictionaryPrefUpdate dict_update(local_state, 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KioskAppManager::kKioskDictionaryName); 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dict_update->SetString(name_key, name); 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dict_update->SetString(icon_path_key, icon_path.value()); 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_path_ = icon_path; 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 38581843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)void KioskAppData::SetCache(const std::string& name, const SkBitmap& icon) { 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_ = gfx::ImageSkia::CreateFrom1xBitmap(icon); 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_.MakeThreadSafe(); 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<unsigned char> image_data; 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(gfx::PNGCodec::EncodeBGRASkBitmap(icon, false, &image_data)); 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raw_icon_ = new base::RefCountedString; 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raw_icon_->data().assign(image_data.begin(), image_data.end()); 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath cache_dir; 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (delegate_) 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate_->GetKioskAppIconCacheDir(&cache_dir); 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath icon_path = 39990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) cache_dir.AppendASCII(app_id_).AddExtension(kIconFileExtension); 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::GetBlockingPool()->PostTask( 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&SaveIconToLocalOnBlockingPool, icon_path, raw_icon_)); 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 40481843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) SetCache(name, icon_path); 40581843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)} 40681843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) 40781843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)void KioskAppData::OnExtensionIconLoaded(const gfx::Image& icon) { 40881843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) if (icon.IsEmpty()) { 40981843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) LOG(WARNING) << "Failed to load icon from installed app" 41081843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) << ", id=" << app_id_; 41181843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) SetCache(name_, *extensions::IconsInfo::GetDefaultAppIcon().bitmap()); 41281843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) } else { 41381843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) SetCache(name_, icon.AsBitmap()); 41481843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) } 41581843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) 41681843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) SetStatus(STATUS_LOADED); 41781843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)} 41881843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) 41981843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)void KioskAppData::OnIconLoadSuccess( 42081843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) const scoped_refptr<base::RefCountedString>& raw_icon, 42181843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) const gfx::ImageSkia& icon) { 42281843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 42381843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) raw_icon_ = raw_icon; 42481843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) icon_ = icon; 42581843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) SetStatus(STATUS_LOADED); 42681843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)} 42781843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) 42881843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)void KioskAppData::OnIconLoadFailure() { 42981843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) // Re-fetch data from web store when failed to load cached data. 43081843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) StartFetch(); 43181843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)} 43281843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) 43381843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles)void KioskAppData::OnWebstoreParseSuccess(const SkBitmap& icon) { 43481843c7b1423e241009db79d34acf2450330fcc5Torne (Richard Coles) SetCache(name_, icon); 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetStatus(STATUS_LOADED); 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppData::OnWebstoreParseFailure() { 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetStatus(STATUS_ERROR); 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppData::StartFetch() { 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webstore_fetcher_.reset(new extensions::WebstoreDataFetcher( 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRequestContextGetter(), 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL(), 44790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) app_id_)); 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webstore_fetcher_->Start(); 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppData::OnWebstoreRequestFailure() { 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetStatus(STATUS_ERROR); 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppData::OnWebstoreResponseParseSuccess( 456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<base::DictionaryValue> webstore_data) { 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Takes ownership of |webstore_data|. 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webstore_fetcher_.reset(); 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string manifest; 461f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!CheckResponseKeyValue(webstore_data.get(), kManifestKey, &manifest)) 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 464f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!CheckResponseKeyValue(webstore_data.get(), kLocalizedNameKey, &name_)) 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string icon_url_string; 468f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!CheckResponseKeyValue(webstore_data.get(), kIconUrlKey, 469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &icon_url_string)) 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 47158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL icon_url = GURL(extension_urls::GetWebstoreLaunchURL()).Resolve( 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_url_string); 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!icon_url.is_valid()) { 47558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) LOG(ERROR) << "Webstore response error (icon url): " 476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << ValueToString(webstore_data.get()); 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnWebstoreResponseParseFailure(kInvalidWebstoreResponseError); 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // WebstoreDataParser deletes itself when done. 48290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) (new WebstoreDataParser(AsWeakPtr()))->Start(app_id_, 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) manifest, 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_url, 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRequestContextGetter()); 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppData::OnWebstoreResponseParseFailure(const std::string& error) { 48958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) LOG(ERROR) << "Webstore failed for kiosk app " << app_id_ 49058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) << ", " << error; 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webstore_fetcher_.reset(); 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetStatus(STATUS_ERROR); 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 49558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool KioskAppData::CheckResponseKeyValue(const base::DictionaryValue* response, 49658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const char* key, 49758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string* value) { 49858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!response->GetString(key, value)) { 49958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) LOG(ERROR) << "Webstore response error (" << key 50058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) << "): " << ValueToString(response); 50158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) OnWebstoreResponseParseFailure(kInvalidWebstoreResponseError); 50258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 50358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 50458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 50558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 50658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace chromeos 508