15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/screensaver/screensaver_view.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/login/existing_user_controller.h"
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/policy/app_pack_updater.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/chromeos/profiles/profile_helper.h"
2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/extensions/extension_garbage_collector_chromeos.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/sandboxed_unpacker.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/login/login_state.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
31a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "extensions/common/file_util.h"
32c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/wm/core/user_activity_detector.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::Extension;
3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)using extensions::ExtensionGarbageCollectorChromeOS;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::SandboxedUnpacker;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)ExtensionService* GetDefaultExtensionService() {
43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Profile* default_profile = ProfileHelper::GetSigninProfile();
4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!default_profile)
4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return NULL;
4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return extensions::ExtensionSystem::Get(
4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      default_profile)->extension_service();
4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)ExtensionGarbageCollectorChromeOS* GetDefaultExtensionGarbageCollector() {
510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  Profile* default_profile = ProfileHelper::GetSigninProfile();
520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!default_profile)
530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return NULL;
5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return ExtensionGarbageCollectorChromeOS::Get(default_profile);
550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef base::Callback<void(
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<Extension>,
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath&)> UnpackCallback;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ScreensaverUnpackerClient
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public extensions::SandboxedUnpackerClient {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScreensaverUnpackerClient(const base::FilePath& crx_path,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const UnpackCallback& unpacker_callback)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : crx_path_(crx_path),
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        unpack_callback_(unpacker_callback) {}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnUnpackSuccess(const base::FilePath& temp_dir,
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               const base::FilePath& extension_root,
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               const base::DictionaryValue* original_manifest,
727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                               const Extension* extension,
737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                               const SkBitmap& install_icon) OVERRIDE;
74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void OnUnpackFailure(const base::string16& error) OVERRIDE;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ScreensaverUnpackerClient() {}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void LoadScreensaverExtension(
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::FilePath& extension_base_path,
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::FilePath& screensaver_extension_path);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void NotifyAppPackOfDamagedFile();
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath crx_path_;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UnpackCallback unpack_callback_;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScreensaverUnpackerClient);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScreensaverUnpackerClient::OnUnpackSuccess(
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& temp_dir,
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& extension_root,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::DictionaryValue* original_manifest,
967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const Extension* extension,
977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const SkBitmap& install_icon) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::BrowserThread::PostTask(
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::BrowserThread::FILE,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&ScreensaverUnpackerClient::LoadScreensaverExtension,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 this,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 temp_dir,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 extension_root));
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ScreensaverUnpackerClient::OnUnpackFailure(const base::string16& error) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(ERROR) << "Couldn't unpack screensaver extension. Error: " << error;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotifyAppPackOfDamagedFile();
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScreensaverUnpackerClient::LoadScreensaverExtension(
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& extension_base_path,
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& screensaver_extension_path) {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // TODO(rkc): This is a HACK, please remove this method from extension
11858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // service once this code is deprecated. See crbug.com/280363
11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ExtensionGarbageCollectorChromeOS* gc = GetDefaultExtensionGarbageCollector();
1200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (gc)
1210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    gc->disable_garbage_collection();
12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<Extension> screensaver_extension =
125a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      extensions::file_util::LoadExtension(screensaver_extension_path,
126a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                           extensions::Manifest::COMPONENT,
127a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                           Extension::NO_FLAGS,
128a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                           &error);
1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!screensaver_extension.get()) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Could not load screensaver extension from: "
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << screensaver_extension_path.value() << " due to: " << error;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyAppPackOfDamagedFile();
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::BrowserThread::PostTask(
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::BrowserThread::UI,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          unpack_callback_,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          screensaver_extension,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extension_base_path));
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScreensaverUnpackerClient::NotifyAppPackOfDamagedFile() {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::BrowserThread::PostTask(
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::BrowserThread::UI, FROM_HERE,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&ScreensaverUnpackerClient::NotifyAppPackOfDamagedFile,
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   this));
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  policy::BrowserPolicyConnectorChromeOS* connector =
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      g_browser_process->platform_part()->browser_policy_connector_chromeos();
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy::AppPackUpdater* updater = connector->GetAppPackUpdater();
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (updater)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    updater->OnDamagedFileDetected(crx_path_);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)KioskModeScreensaver::KioskModeScreensaver()
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : weak_ptr_factory_(this) {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chromeos::KioskModeSettings* kiosk_mode_settings =
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chromeos::KioskModeSettings::Get();
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (kiosk_mode_settings->is_initialized()) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetScreensaverCrxPath();
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kiosk_mode_settings->Initialize(base::Bind(
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &KioskModeScreensaver::GetScreensaverCrxPath,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        weak_ptr_factory_.GetWeakPtr()));
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)KioskModeScreensaver::~KioskModeScreensaver() {
178d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // If we are shutting down the system might already be gone and we shouldn't
179d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // do anything (see crbug.com/288216).
180d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!g_browser_process || g_browser_process->IsShuttingDown())
181d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
182d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the extension was unpacked.
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!extension_base_path_.empty()) {
18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // TODO(rkc): This is a HACK, please remove this method from extension
18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // service once this code is deprecated. See crbug.com/280363
18746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ExtensionGarbageCollectorChromeOS* gc =
18846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        GetDefaultExtensionGarbageCollector();
1890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (gc)
1900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      gc->enable_garbage_collection();
19158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Delete it.
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::BrowserThread::PostTask(
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::BrowserThread::FILE,
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(
197a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            &extensions::file_util::DeleteFile, extension_base_path_, true));
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In case we're shutting down without ever triggering the active
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // notification and/or logging in.
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ash::Shell::GetInstance() &&
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ash::Shell::GetInstance()->user_activity_detector() &&
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ash::Shell::GetInstance()->user_activity_detector()->HasObserver(this))
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ash::Shell::GetInstance()->user_activity_detector()->RemoveObserver(this);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void KioskModeScreensaver::GetScreensaverCrxPath() {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chromeos::KioskModeSettings::Get()->GetScreensaverPath(
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&KioskModeScreensaver::ScreensaverPathCallback,
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void KioskModeScreensaver::ScreensaverPathCallback(
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& screensaver_crx) {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (screensaver_crx.empty())
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ExtensionService* extension_service = GetDefaultExtensionService();
220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!extension_service)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::FilePath extensions_dir = extension_service->install_directory();
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SandboxedUnpacker> screensaver_unpacker(
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new SandboxedUnpacker(
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          screensaver_crx,
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          extensions::Manifest::COMPONENT,
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Extension::NO_FLAGS,
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extensions_dir,
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          content::BrowserThread::GetMessageLoopProxyForThread(
2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              content::BrowserThread::FILE).get(),
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          new ScreensaverUnpackerClient(
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              screensaver_crx,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              base::Bind(
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &KioskModeScreensaver::SetupScreensaver,
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  weak_ptr_factory_.GetWeakPtr()))));
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fire off the unpacker on the file thread; don't need it to return.
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::BrowserThread::PostTask(
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::BrowserThread::FILE,
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &SandboxedUnpacker::Start, screensaver_unpacker.get()));
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void KioskModeScreensaver::SetupScreensaver(
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<Extension> extension,
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& extension_base_path) {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension_base_path_ = extension_base_path;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the user is already logged in, don't need to display the screensaver.
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (chromeos::LoginState::Get()->IsUserLoggedIn())
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ash::Shell::GetInstance()->user_activity_detector()->AddObserver(this);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ExtensionService* extension_service = GetDefaultExtensionService();
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the extension to the extension service and display the screensaver.
259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (extension_service) {
260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    extension_service->AddExtension(extension.get());
261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ash::ShowScreensaver(
2627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        extensions::AppLaunchInfo::GetFullLaunchURL(extension.get()));
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
264a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    LOG(ERROR) << "Couldn't get extension system. Unable to load screensaver!";
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShutdownKioskModeScreensaver();
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid KioskModeScreensaver::OnUserActivity(const ui::Event* event) {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We don't want to handle further user notifications; we'll either login
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the user and close out or or at least close the screensaver.
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ash::Shell::GetInstance()->user_activity_detector()->RemoveObserver(this);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Find the retail mode login page.
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (LoginDisplayHostImpl::default_host()) {
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    LoginDisplayHostImpl* webui_host =
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        static_cast<LoginDisplayHostImpl*>(
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            LoginDisplayHostImpl::default_host());
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OobeUI* oobe_ui = webui_host->GetOobeUI();
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Show the login spinner.
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (oobe_ui)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      oobe_ui->ShowRetailModeLoginSpinner();
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Close the screensaver, our login spinner is already showing.
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ash::CloseScreensaver();
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Log us in.
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExistingUserController* controller =
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ExistingUserController::current_controller();
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (controller && !chromeos::LoginState::Get()->IsUserLoggedIn())
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      controller->LoginAsRetailModeUser();
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No default host for the WebUiLoginDisplay means that we're already in the
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // process of logging in - shut down screensaver and do nothing else.
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ash::CloseScreensaver();
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShutdownKioskModeScreensaver();
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static KioskModeScreensaver* g_kiosk_mode_screensaver = NULL;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InitializeKioskModeScreensaver() {
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_kiosk_mode_screensaver) {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(WARNING) << "Screensaver was already initialized";
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_kiosk_mode_screensaver = new KioskModeScreensaver();
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShutdownKioskModeScreensaver() {
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete g_kiosk_mode_screensaver;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_kiosk_mode_screensaver = NULL;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
319