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" 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/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" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/extensions/extension_util.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/webstore_data_fetcher.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/webstore_install_helper.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/image_decoder.h" 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h" 286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "extensions/browser/image_loader.h" 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/common/constants.h" 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/extension_urls.h" 313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/manifest.h" 323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/manifest_constants.h" 33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/manifest_handlers/icons_handler.h" 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/codec/png_codec.h" 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/image/image.h" 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::BrowserThread; 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace chromeos { 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Keys for local state data. See sample layout in KioskAppManager. 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kKeyName[] = "name"; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kKeyIcon[] = "icon"; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kInvalidWebstoreResponseError[] = "Invalid Chrome Web Store reponse"; 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Icon file extension. 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kIconFileExtension[] = ".png"; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Save |raw_icon| for given |app_id|. 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SaveIconToLocalOnBlockingPool( 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& icon_path, 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::RefCountedString> raw_icon) { 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath dir = icon_path.DirName(); 597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!base::PathExists(dir)) 60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CHECK(base::CreateDirectory(dir)); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK_EQ(static_cast<int>(raw_icon->size()), 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::WriteFile(icon_path, 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) raw_icon->data().c_str(), raw_icon->size())); 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Returns true for valid kiosk app manifest. 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool IsValidKioskAppManifest(const extensions::Manifest& manifest) { 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool kiosk_enabled; 703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (manifest.GetBoolean(extensions::manifest_keys::kKioskEnabled, 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &kiosk_enabled)) { 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return kiosk_enabled; 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)std::string ValueToString(const base::Value* value) { 7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string json; 8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::JSONWriter::Write(value, &json); 8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return json; 8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// KioskAppData::IconLoader 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Loads locally stored icon data and decode it. 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class KioskAppData::IconLoader : public ImageDecoder::Delegate { 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) enum LoadResult { 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SUCCESS, 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FAILED_TO_LOAD, 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FAILED_TO_DECODE, 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IconLoader(const base::WeakPtr<KioskAppData>& client, 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& icon_path) 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : client_(client), 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_path_(icon_path), 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) load_result_(SUCCESS) {} 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Start() { 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool(); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::SequencedWorkerPool::SequenceToken token = pool->GetSequenceToken(); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task_runner_ = pool->GetSequencedTaskRunnerWithShutdownBehavior( 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) token, 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task_runner_->PostTask(FROM_HERE, 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&IconLoader::LoadOnBlockingPool, 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) friend class base::RefCountedThreadSafe<IconLoader>; 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~IconLoader() {} 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Loads the icon from locally stored |icon_path_| on the blocking pool 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void LoadOnBlockingPool() { 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(task_runner_->RunsTasksOnCurrentThread()); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string data; 12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!base::ReadFileToString(base::FilePath(icon_path_), &data)) { 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReportResultOnBlockingPool(FAILED_TO_LOAD); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raw_icon_ = base::RefCountedString::TakeString(&data); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<ImageDecoder> image_decoder = new ImageDecoder( 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, raw_icon_->data(), ImageDecoder::DEFAULT_CODEC); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) image_decoder->Start(task_runner_); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void ReportResultOnBlockingPool(LoadResult result) { 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(task_runner_->RunsTasksOnCurrentThread()); 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) load_result_ = result; 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask( 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::UI, 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&IconLoader::ReportResultOnUIThread, 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void NotifyClient() { 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!client_) 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (load_result_ == SUCCESS) 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_->OnIconLoadSuccess(raw_icon_, icon_); 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_->OnIconLoadFailure(); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void ReportResultOnUIThread() { 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyClient(); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete this; 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ImageDecoder::Delegate overrides: 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnImageDecoded(const ImageDecoder* decoder, 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SkBitmap& decoded_image) OVERRIDE { 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_ = gfx::ImageSkia::CreateFrom1xBitmap(decoded_image); 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_.MakeThreadSafe(); 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReportResultOnBlockingPool(SUCCESS); 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnDecodeImageFailed(const ImageDecoder* decoder) OVERRIDE { 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReportResultOnBlockingPool(FAILED_TO_DECODE); 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtr<KioskAppData> client_; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath icon_path_; 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LoadResult load_result_; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> task_runner_; 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::ImageSkia icon_; 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::RefCountedString> raw_icon_; 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(IconLoader); 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// KioskAppData::WebstoreDataParser 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use WebstoreInstallHelper to parse the manifest and decode the icon. 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class KioskAppData::WebstoreDataParser 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public extensions::WebstoreInstallHelper::Delegate { 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit WebstoreDataParser(const base::WeakPtr<KioskAppData>& client) 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : client_(client) {} 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Start(const std::string& app_id, 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& manifest, 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& icon_url, 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::URLRequestContextGetter* context_getter) { 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<extensions::WebstoreInstallHelper> webstore_helper = 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new extensions::WebstoreInstallHelper(this, 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app_id, 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) manifest, 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "", // No icon data. 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_url, 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context_getter); 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webstore_helper->Start(); 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) friend class base::RefCounted<WebstoreDataParser>; 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~WebstoreDataParser() {} 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void ReportFailure() { 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (client_) 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_->OnWebstoreParseFailure(); 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delete this; 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // WebstoreInstallHelper::Delegate overrides: 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnWebstoreParseSuccess( 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& id, 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SkBitmap& icon, 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* parsed_manifest) OVERRIDE { 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Takes ownership of |parsed_manifest|. 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extensions::Manifest manifest( 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extensions::Manifest::INVALID_LOCATION, 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::DictionaryValue>(parsed_manifest)); 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!IsValidKioskAppManifest(manifest)) { 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ReportFailure(); 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (client_) 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_->OnWebstoreParseSuccess(icon); 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete this; 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnWebstoreParseFailure( 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& id, 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InstallHelperResultCode result_code, 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& error_message) OVERRIDE { 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ReportFailure(); 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtr<KioskAppData> client_; 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(WebstoreDataParser); 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// KioskAppData 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)KioskAppData::KioskAppData(KioskAppDataDelegate* delegate, 25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& app_id, 26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& user_id) 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : delegate_(delegate), 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) status_(STATUS_INIT), 26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) app_id_(app_id), 26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) user_id_(user_id) { 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)KioskAppData::~KioskAppData() {} 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppData::Load() { 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetStatus(STATUS_LOADING); 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (LoadFromCache()) 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartFetch(); 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppData::ClearCache() { 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PrefService* local_state = g_browser_process->local_state(); 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DictionaryPrefUpdate dict_update(local_state, 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KioskAppManager::kKioskDictionaryName); 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 28490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string app_key = std::string(KioskAppManager::kKeyApps) + '.' + app_id_; 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dict_update->Remove(app_key, NULL); 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!icon_path_.empty()) { 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostBlockingPoolTask( 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 2907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(base::IgnoreResult(&base::DeleteFile), icon_path_, false)); 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void KioskAppData::LoadFromInstalledApp(Profile* profile, 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const extensions::Extension* app) { 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetStatus(STATUS_LOADING); 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!app) { 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app = extensions::ExtensionSystem::Get(profile) 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ->extension_service() 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ->GetInstalledExtension(app_id_); 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(app_id_, app->id()); 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) name_ = app->name(); 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const int kIconSize = extension_misc::EXTENSION_ICON_LARGE; 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extensions::ExtensionResource image = extensions::IconsInfo::GetIconResource( 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app, kIconSize, ExtensionIconSet::MATCH_BIGGER); 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extensions::ImageLoader::Get(profile)->LoadImageAsync( 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app, image, gfx::Size(kIconSize, kIconSize), 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&KioskAppData::OnExtensionIconLoaded, AsWeakPtr())); 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool KioskAppData::IsLoading() const { 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status_ == STATUS_LOADING; 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppData::SetStatus(Status status) { 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status_ == status) 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) status_ = status; 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!delegate_) 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (status_) { 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case STATUS_INIT: 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case STATUS_LOADING: 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case STATUS_LOADED: 33490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delegate_->OnKioskAppDataChanged(app_id_); 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case STATUS_ERROR: 33790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delegate_->OnKioskAppDataLoadFailure(app_id_); 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 339116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)net::URLRequestContextGetter* KioskAppData::GetRequestContextGetter() { 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return g_browser_process->system_request_context(); 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool KioskAppData::LoadFromCache() { 34790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string app_key = std::string(KioskAppManager::kKeyApps) + '.' + app_id_; 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string name_key = app_key + '.' + kKeyName; 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string icon_path_key = app_key + '.' + kKeyIcon; 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PrefService* local_state = g_browser_process->local_state(); 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue* dict = 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_state->GetDictionary(KioskAppManager::kKioskDictionaryName); 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_path_.clear(); 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string icon_path_string; 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!dict->GetString(name_key, &name_) || 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !dict->GetString(icon_path_key, &icon_path_string)) { 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_path_ = base::FilePath(icon_path_string); 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // IconLoader deletes itself when done. 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (new IconLoader(AsWeakPtr(), icon_path_))->Start(); 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppData::SetCache(const std::string& name, 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& icon_path) { 37090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string app_key = std::string(KioskAppManager::kKeyApps) + '.' + app_id_; 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string name_key = app_key + '.' + kKeyName; 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string icon_path_key = app_key + '.' + kKeyIcon; 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PrefService* local_state = g_browser_process->local_state(); 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DictionaryPrefUpdate dict_update(local_state, 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KioskAppManager::kKioskDictionaryName); 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dict_update->SetString(name_key, name); 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dict_update->SetString(icon_path_key, icon_path.value()); 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_path_ = icon_path; 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void KioskAppData::SetCache(const std::string& name, const SkBitmap& icon) { 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_ = gfx::ImageSkia::CreateFrom1xBitmap(icon); 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_.MakeThreadSafe(); 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<unsigned char> image_data; 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(gfx::PNGCodec::EncodeBGRASkBitmap(icon, false, &image_data)); 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raw_icon_ = new base::RefCountedString; 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raw_icon_->data().assign(image_data.begin(), image_data.end()); 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath cache_dir; 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (delegate_) 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate_->GetKioskAppIconCacheDir(&cache_dir); 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath icon_path = 39690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) cache_dir.AppendASCII(app_id_).AddExtension(kIconFileExtension); 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::GetBlockingPool()->PostTask( 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&SaveIconToLocalOnBlockingPool, icon_path, raw_icon_)); 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetCache(name, icon_path); 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void KioskAppData::OnExtensionIconLoaded(const gfx::Image& icon) { 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (icon.IsEmpty()) { 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(WARNING) << "Failed to load icon from installed app" 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << ", id=" << app_id_; 4085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SetCache(name_, *extensions::util::GetDefaultAppIcon().bitmap()); 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetCache(name_, icon.AsBitmap()); 4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetStatus(STATUS_LOADED); 4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void KioskAppData::OnIconLoadSuccess( 4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const scoped_refptr<base::RefCountedString>& raw_icon, 4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::ImageSkia& icon) { 4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raw_icon_ = raw_icon; 4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) icon_ = icon; 4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetStatus(STATUS_LOADED); 4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void KioskAppData::OnIconLoadFailure() { 4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Re-fetch data from web store when failed to load cached data. 4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StartFetch(); 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void KioskAppData::OnWebstoreParseSuccess(const SkBitmap& icon) { 4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetCache(name_, icon); 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetStatus(STATUS_LOADED); 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppData::OnWebstoreParseFailure() { 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetStatus(STATUS_ERROR); 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppData::StartFetch() { 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webstore_fetcher_.reset(new extensions::WebstoreDataFetcher( 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRequestContextGetter(), 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL(), 44490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) app_id_)); 445116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch webstore_fetcher_->set_max_auto_retries(3); 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webstore_fetcher_->Start(); 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppData::OnWebstoreRequestFailure() { 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetStatus(STATUS_ERROR); 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppData::OnWebstoreResponseParseSuccess( 454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<base::DictionaryValue> webstore_data) { 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Takes ownership of |webstore_data|. 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webstore_fetcher_.reset(); 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string manifest; 459f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!CheckResponseKeyValue(webstore_data.get(), kManifestKey, &manifest)) 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 462f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!CheckResponseKeyValue(webstore_data.get(), kLocalizedNameKey, &name_)) 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string icon_url_string; 466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!CheckResponseKeyValue(webstore_data.get(), kIconUrlKey, 467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &icon_url_string)) 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 46958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL icon_url = GURL(extension_urls::GetWebstoreLaunchURL()).Resolve( 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_url_string); 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!icon_url.is_valid()) { 47358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) LOG(ERROR) << "Webstore response error (icon url): " 474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) << ValueToString(webstore_data.get()); 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnWebstoreResponseParseFailure(kInvalidWebstoreResponseError); 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // WebstoreDataParser deletes itself when done. 48090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) (new WebstoreDataParser(AsWeakPtr()))->Start(app_id_, 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) manifest, 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) icon_url, 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRequestContextGetter()); 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KioskAppData::OnWebstoreResponseParseFailure(const std::string& error) { 48758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) LOG(ERROR) << "Webstore failed for kiosk app " << app_id_ 48858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) << ", " << error; 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webstore_fetcher_.reset(); 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetStatus(STATUS_ERROR); 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 49358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool KioskAppData::CheckResponseKeyValue(const base::DictionaryValue* response, 49458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const char* key, 49558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string* value) { 49658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!response->GetString(key, value)) { 49758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) LOG(ERROR) << "Webstore response error (" << key 49858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) << "): " << ValueToString(response); 49958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) OnWebstoreResponseParseFailure(kInvalidWebstoreResponseError); 50058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 50158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 50258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 50358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 50458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace chromeos 506