1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/chromeos/app_mode/app_session_lifetime.h" 6 7 #include "apps/app_window.h" 8 #include "apps/app_window_registry.h" 9 #include "base/basictypes.h" 10 #include "base/bind.h" 11 #include "base/lazy_instance.h" 12 #include "base/message_loop/message_loop.h" 13 #include "base/prefs/pref_service.h" 14 #include "chrome/browser/browser_process.h" 15 #include "chrome/browser/chromeos/app_mode/kiosk_app_update_service.h" 16 #include "chrome/browser/chromeos/app_mode/kiosk_mode_idle_app_name_notification.h" 17 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h" 18 #include "chrome/browser/chromeos/login/users/user_manager.h" 19 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" 20 #include "chrome/browser/lifetime/application_lifetime.h" 21 #include "chrome/browser/profiles/profile.h" 22 #include "chrome/browser/ui/browser.h" 23 #include "chrome/browser/ui/browser_list.h" 24 #include "chrome/browser/ui/browser_list_observer.h" 25 #include "chrome/browser/ui/browser_window.h" 26 #include "chrome/browser/ui/tabs/tab_strip_model.h" 27 #include "chrome/common/pref_names.h" 28 #include "chromeos/network/network_state.h" 29 #include "chromeos/network/network_state_handler.h" 30 #include "content/public/browser/web_contents.h" 31 32 using apps::AppWindowRegistry; 33 34 namespace chromeos { 35 36 namespace { 37 38 // AppWindowHandler watches for app window and exits the session when the 39 // last app window is closed. 40 class AppWindowHandler : public AppWindowRegistry::Observer { 41 public: 42 AppWindowHandler() : window_registry_(NULL) {} 43 virtual ~AppWindowHandler() {} 44 45 void Init(Profile* profile) { 46 DCHECK(!window_registry_); 47 window_registry_ = AppWindowRegistry::Get(profile); 48 if (window_registry_) 49 window_registry_->AddObserver(this); 50 } 51 52 private: 53 // apps::AppWindowRegistry::Observer overrides: 54 virtual void OnAppWindowRemoved(apps::AppWindow* app_window) OVERRIDE { 55 if (window_registry_->app_windows().empty()) { 56 if (DemoAppLauncher::IsDemoAppSession( 57 chromeos::UserManager::Get()->GetActiveUser()->email())) { 58 // If we were in demo mode, we disabled all our network technologies, 59 // re-enable them. 60 NetworkStateHandler* handler = 61 NetworkHandler::Get()->network_state_handler(); 62 handler->SetTechnologyEnabled( 63 NetworkTypePattern::NonVirtual(), 64 true, 65 chromeos::network_handler::ErrorCallback()); 66 } 67 chrome::AttemptUserExit(); 68 window_registry_->RemoveObserver(this); 69 } 70 } 71 72 apps::AppWindowRegistry* window_registry_; 73 74 DISALLOW_COPY_AND_ASSIGN(AppWindowHandler); 75 }; 76 77 base::LazyInstance<AppWindowHandler> app_window_handler 78 = LAZY_INSTANCE_INITIALIZER; 79 80 // BrowserWindowHandler monitors Browser object being created during 81 // a kiosk session, log info such as URL so that the code path could be 82 // fixed and closes the just opened browser window. 83 class BrowserWindowHandler : public chrome::BrowserListObserver { 84 public: 85 BrowserWindowHandler() { 86 BrowserList::AddObserver(this); 87 } 88 virtual ~BrowserWindowHandler() { 89 BrowserList::RemoveObserver(this); 90 } 91 92 private: 93 void HandleBrowser(Browser* browser) { 94 content::WebContents* active_tab = 95 browser->tab_strip_model()->GetActiveWebContents(); 96 std::string url_string = 97 active_tab ? active_tab->GetURL().spec() : std::string(); 98 LOG(WARNING) << "Browser opened in kiosk session" 99 << ", url=" << url_string; 100 101 browser->window()->Close(); 102 } 103 104 // chrome::BrowserListObserver overrides: 105 virtual void OnBrowserAdded(Browser* browser) OVERRIDE { 106 base::MessageLoop::current()->PostTask( 107 FROM_HERE, 108 base::Bind(&BrowserWindowHandler::HandleBrowser, 109 base::Unretained(this), // LazyInstance, always valid 110 browser)); 111 } 112 113 DISALLOW_COPY_AND_ASSIGN(BrowserWindowHandler); 114 }; 115 116 base::LazyInstance<BrowserWindowHandler> browser_window_handler 117 = LAZY_INSTANCE_INITIALIZER; 118 119 } // namespace 120 121 void InitAppSession(Profile* profile, const std::string& app_id) { 122 // Binds the session lifetime with app window counts. 123 CHECK(app_window_handler == NULL); 124 app_window_handler.Get().Init(profile); 125 126 CHECK(browser_window_handler == NULL); 127 browser_window_handler.Get(); 128 129 // For a demo app, we don't need to either setup the update service or 130 // the idle app name notification. 131 if (DemoAppLauncher::IsDemoAppSession( 132 chromeos::UserManager::Get()->GetActiveUser()->email())) 133 return; 134 135 // Set the app_id for the current instance of KioskAppUpdateService. 136 KioskAppUpdateService* update_service = 137 KioskAppUpdateServiceFactory::GetForProfile(profile); 138 DCHECK(update_service); 139 if (update_service) 140 update_service->set_app_id(app_id); 141 142 // If the device is not enterprise managed, set prefs to reboot after update 143 // and create a user security message which shows the user the application 144 // name and author after some idle timeout. 145 policy::BrowserPolicyConnectorChromeOS* connector = 146 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 147 if (!connector->IsEnterpriseManaged()) { 148 PrefService* local_state = g_browser_process->local_state(); 149 local_state->SetBoolean(prefs::kRebootAfterUpdate, true); 150 KioskModeIdleAppNameNotification::Initialize(); 151 } 152 } 153 154 } // namespace chromeos 155