This source file includes following definitions.
- GetDefaultExtensionService
- unpack_callback_
- OnUnpackSuccess
- OnUnpackFailure
- LoadScreensaverExtension
- NotifyAppPackOfDamagedFile
- GetScreensaverCrxPath
- ScreensaverPathCallback
- SetupScreensaver
- OnUserActivity
- InitializeKioskModeScreensaver
- ShutdownKioskModeScreensaver
#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.h"
#include "ash/screensaver/screensaver_view.h"
#include "ash/shell.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
#include "chrome/browser/chromeos/login/existing_user_controller.h"
#include "chrome/browser/chromeos/login/login_display_host_impl.h"
#include "chrome/browser/chromeos/policy/app_pack_updater.h"
#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/extensions/extension_garbage_collector.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/sandboxed_unpacker.h"
#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
#include "chrome/common/extensions/extension_file_util.h"
#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chromeos/login/login_state.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/extension.h"
#include "ui/wm/core/user_activity_detector.h"
using extensions::Extension;
using extensions::SandboxedUnpacker;
namespace chromeos {
namespace {
ExtensionService* GetDefaultExtensionService() {
Profile* default_profile = ProfileHelper::GetSigninProfile();
if (!default_profile)
return NULL;
return extensions::ExtensionSystem::Get(
default_profile)->extension_service();
}
typedef base::Callback<void(
scoped_refptr<Extension>,
const base::FilePath&)> UnpackCallback;
class ScreensaverUnpackerClient
: public extensions::SandboxedUnpackerClient {
public:
ScreensaverUnpackerClient(const base::FilePath& crx_path,
const UnpackCallback& unpacker_callback)
: crx_path_(crx_path),
unpack_callback_(unpacker_callback) {}
virtual void OnUnpackSuccess(const base::FilePath& temp_dir,
const base::FilePath& extension_root,
const base::DictionaryValue* original_manifest,
const Extension* extension,
const SkBitmap& install_icon) OVERRIDE;
virtual void OnUnpackFailure(const base::string16& error) OVERRIDE;
protected:
virtual ~ScreensaverUnpackerClient() {}
private:
void LoadScreensaverExtension(
const base::FilePath& extension_base_path,
const base::FilePath& screensaver_extension_path);
void NotifyAppPackOfDamagedFile();
base::FilePath crx_path_;
UnpackCallback unpack_callback_;
DISALLOW_COPY_AND_ASSIGN(ScreensaverUnpackerClient);
};
void ScreensaverUnpackerClient::OnUnpackSuccess(
const base::FilePath& temp_dir,
const base::FilePath& extension_root,
const base::DictionaryValue* original_manifest,
const Extension* extension,
const SkBitmap& install_icon) {
content::BrowserThread::PostTask(
content::BrowserThread::FILE,
FROM_HERE,
base::Bind(&ScreensaverUnpackerClient::LoadScreensaverExtension,
this,
temp_dir,
extension_root));
}
void ScreensaverUnpackerClient::OnUnpackFailure(const base::string16& error) {
LOG(ERROR) << "Couldn't unpack screensaver extension. Error: " << error;
NotifyAppPackOfDamagedFile();
}
void ScreensaverUnpackerClient::LoadScreensaverExtension(
const base::FilePath& extension_base_path,
const base::FilePath& screensaver_extension_path) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
ExtensionService* service = GetDefaultExtensionService();
if (service)
service->garbage_collector()->disable_garbage_collection();
std::string error;
scoped_refptr<Extension> screensaver_extension =
extension_file_util::LoadExtension(screensaver_extension_path,
extensions::Manifest::COMPONENT,
Extension::NO_FLAGS,
&error);
if (!screensaver_extension.get()) {
LOG(ERROR) << "Could not load screensaver extension from: "
<< screensaver_extension_path.value() << " due to: " << error;
NotifyAppPackOfDamagedFile();
return;
}
content::BrowserThread::PostTask(
content::BrowserThread::UI,
FROM_HERE,
base::Bind(
unpack_callback_,
screensaver_extension,
extension_base_path));
}
void ScreensaverUnpackerClient::NotifyAppPackOfDamagedFile() {
if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE,
base::Bind(&ScreensaverUnpackerClient::NotifyAppPackOfDamagedFile,
this));
return;
}
policy::BrowserPolicyConnectorChromeOS* connector =
g_browser_process->platform_part()->browser_policy_connector_chromeos();
policy::AppPackUpdater* updater = connector->GetAppPackUpdater();
if (updater)
updater->OnDamagedFileDetected(crx_path_);
}
}
KioskModeScreensaver::KioskModeScreensaver()
: weak_ptr_factory_(this) {
chromeos::KioskModeSettings* kiosk_mode_settings =
chromeos::KioskModeSettings::Get();
if (kiosk_mode_settings->is_initialized()) {
GetScreensaverCrxPath();
} else {
kiosk_mode_settings->Initialize(base::Bind(
&KioskModeScreensaver::GetScreensaverCrxPath,
weak_ptr_factory_.GetWeakPtr()));
}
}
KioskModeScreensaver::~KioskModeScreensaver() {
if (!g_browser_process || g_browser_process->IsShuttingDown())
return;
if (!extension_base_path_.empty()) {
ExtensionService* service = GetDefaultExtensionService();
if (service)
service->garbage_collector()->enable_garbage_collection();
content::BrowserThread::PostTask(
content::BrowserThread::FILE,
FROM_HERE,
base::Bind(
&extension_file_util::DeleteFile, extension_base_path_, true));
}
if (ash::Shell::GetInstance() &&
ash::Shell::GetInstance()->user_activity_detector() &&
ash::Shell::GetInstance()->user_activity_detector()->HasObserver(this))
ash::Shell::GetInstance()->user_activity_detector()->RemoveObserver(this);
}
void KioskModeScreensaver::GetScreensaverCrxPath() {
chromeos::KioskModeSettings::Get()->GetScreensaverPath(
base::Bind(&KioskModeScreensaver::ScreensaverPathCallback,
weak_ptr_factory_.GetWeakPtr()));
}
void KioskModeScreensaver::ScreensaverPathCallback(
const base::FilePath& screensaver_crx) {
if (screensaver_crx.empty())
return;
ExtensionService* extension_service = GetDefaultExtensionService();
if (!extension_service)
return;
base::FilePath extensions_dir = extension_service->install_directory();
scoped_refptr<SandboxedUnpacker> screensaver_unpacker(
new SandboxedUnpacker(
screensaver_crx,
extensions::Manifest::COMPONENT,
Extension::NO_FLAGS,
extensions_dir,
content::BrowserThread::GetMessageLoopProxyForThread(
content::BrowserThread::FILE).get(),
new ScreensaverUnpackerClient(
screensaver_crx,
base::Bind(
&KioskModeScreensaver::SetupScreensaver,
weak_ptr_factory_.GetWeakPtr()))));
content::BrowserThread::PostTask(
content::BrowserThread::FILE,
FROM_HERE,
base::Bind(
&SandboxedUnpacker::Start, screensaver_unpacker.get()));
}
void KioskModeScreensaver::SetupScreensaver(
scoped_refptr<Extension> extension,
const base::FilePath& extension_base_path) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
extension_base_path_ = extension_base_path;
if (chromeos::LoginState::Get()->IsUserLoggedIn())
return;
ash::Shell::GetInstance()->user_activity_detector()->AddObserver(this);
ExtensionService* extension_service = GetDefaultExtensionService();
if (extension_service) {
extension_service->AddExtension(extension.get());
ash::ShowScreensaver(
extensions::AppLaunchInfo::GetFullLaunchURL(extension.get()));
} else {
LOG(ERROR) << "Couldn't get extension system. Unable to load screensaver!";
ShutdownKioskModeScreensaver();
}
}
void KioskModeScreensaver::OnUserActivity(const ui::Event* event) {
ash::Shell::GetInstance()->user_activity_detector()->RemoveObserver(this);
if (LoginDisplayHostImpl::default_host()) {
LoginDisplayHostImpl* webui_host =
static_cast<LoginDisplayHostImpl*>(
LoginDisplayHostImpl::default_host());
OobeUI* oobe_ui = webui_host->GetOobeUI();
if (oobe_ui)
oobe_ui->ShowRetailModeLoginSpinner();
ash::CloseScreensaver();
ExistingUserController* controller =
ExistingUserController::current_controller();
if (controller && !chromeos::LoginState::Get()->IsUserLoggedIn())
controller->LoginAsRetailModeUser();
} else {
ash::CloseScreensaver();
}
ShutdownKioskModeScreensaver();
}
static KioskModeScreensaver* g_kiosk_mode_screensaver = NULL;
void InitializeKioskModeScreensaver() {
if (g_kiosk_mode_screensaver) {
LOG(WARNING) << "Screensaver was already initialized";
return;
}
g_kiosk_mode_screensaver = new KioskModeScreensaver();
}
void ShutdownKioskModeScreensaver() {
delete g_kiosk_mode_screensaver;
g_kiosk_mode_screensaver = NULL;
}
}