Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/managed_mode.h" | 5 #include "chrome/browser/managed_mode.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "chrome/browser/browser_process.h" | 8 #include "chrome/browser/browser_process.h" |
| 9 #include "chrome/browser/extensions/extension_service.h" | |
| 9 #include "chrome/browser/extensions/extension_system.h" | 10 #include "chrome/browser/extensions/extension_system.h" |
| 11 #include "chrome/browser/managed_mode_url_filter.h" | |
| 10 #include "chrome/browser/prefs/pref_service.h" | 12 #include "chrome/browser/prefs/pref_service.h" |
| 11 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
| 12 #include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h" | |
| 13 #include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h" | |
| 14 #include "chrome/browser/ui/browser.h" | 14 #include "chrome/browser/ui/browser.h" |
| 15 #include "chrome/browser/ui/browser_list.h" | 15 #include "chrome/browser/ui/browser_list.h" |
| 16 #include "chrome/browser/ui/browser_window.h" | 16 #include "chrome/browser/ui/browser_window.h" |
| 17 #include "chrome/common/chrome_notification_types.h" | 17 #include "chrome/common/chrome_notification_types.h" |
| 18 #include "chrome/common/chrome_switches.h" | 18 #include "chrome/common/chrome_switches.h" |
| 19 #include "chrome/common/pref_names.h" | 19 #include "chrome/common/pref_names.h" |
| 20 #include "content/public/browser/browser_thread.h" | |
| 20 #include "content/public/browser/notification_service.h" | 21 #include "content/public/browser/notification_service.h" |
| 21 #include "grit/generated_resources.h" | 22 #include "grit/generated_resources.h" |
| 22 #include "ui/base/l10n/l10n_util.h" | 23 #include "ui/base/l10n/l10n_util.h" |
| 23 | 24 |
| 25 using content::BrowserThread; | |
| 26 | |
| 27 // A bridge from ManagedMode (which lives on the UI thread) to | |
| 28 // ManagedModeURLFilter (which lives on the IO thread). | |
| 29 class ManagedMode::URLFilterContext { | |
| 30 public: | |
| 31 URLFilterContext() {} | |
| 32 ~URLFilterContext() {} | |
| 33 | |
| 34 const ManagedModeURLFilter* url_filter() const { | |
| 35 return &url_filter_; | |
| 36 } | |
| 37 | |
| 38 void SetActive(bool in_managed_mode) { | |
| 39 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 40 // Because ManagedMode is a singleton, we can pass the pointer to | |
| 41 // |url_filter_| unretained. | |
| 42 BrowserThread::PostTask(BrowserThread::IO, | |
| 43 FROM_HERE, | |
| 44 base::Bind( | |
| 45 &ManagedModeURLFilter::SetActive, | |
| 46 base::Unretained(&url_filter_), | |
| 47 in_managed_mode)); | |
| 48 } | |
| 49 | |
| 50 void ShutdownOnUIThread() { | |
| 51 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 52 BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, this); | |
| 53 } | |
| 54 | |
| 55 private: | |
| 56 ManagedModeURLFilter url_filter_; | |
| 57 | |
| 58 DISALLOW_COPY_AND_ASSIGN(URLFilterContext); | |
| 59 }; | |
| 60 | |
| 24 // static | 61 // static |
| 25 ManagedMode* ManagedMode::GetInstance() { | 62 ManagedMode* ManagedMode::GetInstance() { |
| 26 return Singleton<ManagedMode>::get(); | 63 return Singleton<ManagedMode, LeakySingletonTraits<ManagedMode> >::get(); |
| 27 } | 64 } |
| 28 | 65 |
| 29 // static | 66 // static |
| 30 void ManagedMode::RegisterPrefs(PrefService* prefs) { | 67 void ManagedMode::RegisterPrefs(PrefService* prefs) { |
| 31 prefs->RegisterBooleanPref(prefs::kInManagedMode, false); | 68 prefs->RegisterBooleanPref(prefs::kInManagedMode, false); |
| 32 } | 69 } |
| 33 | 70 |
| 34 // static | 71 // static |
| 35 void ManagedMode::Init(Profile* profile) { | 72 void ManagedMode::Init(Profile* profile) { |
| 36 GetInstance()->InitImpl(profile); | 73 GetInstance()->InitImpl(profile); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 126 void ManagedMode::LeaveManagedMode() { | 163 void ManagedMode::LeaveManagedMode() { |
| 127 GetInstance()->LeaveManagedModeImpl(); | 164 GetInstance()->LeaveManagedModeImpl(); |
| 128 } | 165 } |
| 129 | 166 |
| 130 void ManagedMode::LeaveManagedModeImpl() { | 167 void ManagedMode::LeaveManagedModeImpl() { |
| 131 bool confirmed = PlatformConfirmLeave(); | 168 bool confirmed = PlatformConfirmLeave(); |
| 132 if (confirmed) | 169 if (confirmed) |
| 133 SetInManagedMode(NULL); | 170 SetInManagedMode(NULL); |
| 134 } | 171 } |
| 135 | 172 |
| 173 // static | |
| 174 const ManagedModeURLFilter* ManagedMode::GetURLFilter() { | |
| 175 return GetInstance()->GetURLFilterImpl(); | |
| 176 } | |
| 177 | |
| 178 const ManagedModeURLFilter* ManagedMode::GetURLFilterImpl() { | |
| 179 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 180 return url_filter_context_->url_filter(); | |
| 181 } | |
| 182 | |
| 136 std::string ManagedMode::GetDebugPolicyProviderName() const { | 183 std::string ManagedMode::GetDebugPolicyProviderName() const { |
| 137 // Save the string space in official builds. | 184 // Save the string space in official builds. |
| 138 #ifdef NDEBUG | 185 #ifdef NDEBUG |
| 139 NOTREACHED(); | 186 NOTREACHED(); |
| 140 return std::string(); | 187 return std::string(); |
| 141 #else | 188 #else |
| 142 return "Managed Mode"; | 189 return "Managed Mode"; |
| 143 #endif | 190 #endif |
| 144 } | 191 } |
| 145 | 192 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 181 if (browser->profile()->GetOriginalProfile() == managed_profile_) { | 228 if (browser->profile()->GetOriginalProfile() == managed_profile_) { |
| 182 // Ignore closing browser windows that are in managed mode. | 229 // Ignore closing browser windows that are in managed mode. |
| 183 return; | 230 return; |
| 184 } | 231 } |
| 185 size_t count = browsers_to_close_.erase(browser); | 232 size_t count = browsers_to_close_.erase(browser); |
| 186 DCHECK_EQ(1u, count); | 233 DCHECK_EQ(1u, count); |
| 187 if (browsers_to_close_.empty()) | 234 if (browsers_to_close_.empty()) |
| 188 FinalizeEnter(true); | 235 FinalizeEnter(true); |
| 189 } | 236 } |
| 190 | 237 |
| 191 ManagedMode::ManagedMode() : managed_profile_(NULL) { | 238 ManagedMode::ManagedMode() : managed_profile_(NULL), |
| 239 url_filter_context_(new URLFilterContext) { | |
| 192 BrowserList::AddObserver(this); | 240 BrowserList::AddObserver(this); |
| 193 } | 241 } |
| 194 | 242 |
| 195 ManagedMode::~ManagedMode() { | 243 ManagedMode::~ManagedMode() { |
| 244 // This class usually is a leaky singleton, so this destructor shouldn't be | |
| 245 // called. We still do some cleanup, in case we're owned by a unit test. | |
| 196 BrowserList::RemoveObserver(this); | 246 BrowserList::RemoveObserver(this); |
| 197 DCHECK_EQ(0u, callbacks_.size()); | 247 DCHECK_EQ(0u, callbacks_.size()); |
| 198 DCHECK_EQ(0u, browsers_to_close_.size()); | 248 DCHECK_EQ(0u, browsers_to_close_.size()); |
| 249 url_filter_context_.release()->ShutdownOnUIThread(); | |
| 199 } | 250 } |
| 200 | 251 |
| 201 void ManagedMode::Observe(int type, | 252 void ManagedMode::Observe(int type, |
| 202 const content::NotificationSource& source, | 253 const content::NotificationSource& source, |
| 203 const content::NotificationDetails& details) { | 254 const content::NotificationDetails& details) { |
| 204 // Return early if we don't have any queued callbacks. | 255 // Return early if we don't have any queued callbacks. |
| 205 if (callbacks_.empty()) | 256 if (callbacks_.empty()) |
| 206 return; | 257 return; |
| 207 | 258 |
| 208 switch (type) { | 259 switch (type) { |
| 209 case chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST: { | 260 case chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST: { |
| 210 FinalizeEnter(false); | 261 FinalizeEnter(false); |
| 211 return; | 262 return; |
| 212 } | 263 } |
| 213 case chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED: { | 264 case chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED: { |
| 214 Browser* browser = content::Source<Browser>(source).ptr(); | 265 Browser* browser = content::Source<Browser>(source).ptr(); |
| 215 if (browsers_to_close_.find(browser) != browsers_to_close_.end()) | 266 if (browsers_to_close_.find(browser) != browsers_to_close_.end()) |
| 216 FinalizeEnter(false); | 267 FinalizeEnter(false); |
| 217 return; | 268 return; |
| 218 } | 269 } |
| 219 default: { | 270 case chrome::NOTIFICATION_EXTENSION_LOADED: |
| 271 case chrome::NOTIFICATION_EXTENSION_UNLOADED: { | |
| 272 if (managed_profile_) | |
| 273 UpdateWhitelist(); | |
|
battre
2012/08/14 11:58:33
missing a break here?
Bernhard Bauer
2012/08/14 15:36:57
Oops. Done.
| |
| 274 } | |
| 275 default: | |
| 220 NOTREACHED(); | 276 NOTREACHED(); |
| 221 break; | |
| 222 } | |
| 223 } | 277 } |
| 224 } | 278 } |
| 225 | 279 |
| 226 void ManagedMode::FinalizeEnter(bool result) { | 280 void ManagedMode::FinalizeEnter(bool result) { |
| 227 if (result) | 281 if (result) |
| 228 SetInManagedMode(managed_profile_); | 282 SetInManagedMode(managed_profile_); |
| 229 for (std::vector<EnterCallback>::iterator it = callbacks_.begin(); | 283 for (std::vector<EnterCallback>::iterator it = callbacks_.begin(); |
| 230 it != callbacks_.end(); ++it) { | 284 it != callbacks_.end(); ++it) { |
| 231 it->Run(result); | 285 it->Run(result); |
| 232 } | 286 } |
| 233 callbacks_.clear(); | 287 callbacks_.clear(); |
| 234 browsers_to_close_.clear(); | 288 browsers_to_close_.clear(); |
| 235 registrar_.RemoveAll(); | 289 registrar_.RemoveAll(); |
| 236 } | 290 } |
| 237 | 291 |
| 238 bool ManagedMode::PlatformConfirmEnter() { | 292 bool ManagedMode::PlatformConfirmEnter() { |
| 239 // TODO(bauerb): Show platform-specific confirmation dialog. | 293 // TODO(bauerb): Show platform-specific confirmation dialog. |
| 240 return true; | 294 return true; |
| 241 } | 295 } |
| 242 | 296 |
| 243 bool ManagedMode::PlatformConfirmLeave() { | 297 bool ManagedMode::PlatformConfirmLeave() { |
| 244 // TODO(bauerb): Show platform-specific confirmation dialog. | 298 // TODO(bauerb): Show platform-specific confirmation dialog. |
| 245 return true; | 299 return true; |
| 246 } | 300 } |
| 247 | 301 |
| 248 void ManagedMode::SetInManagedMode(Profile* newly_managed_profile) { | 302 void ManagedMode::SetInManagedMode(Profile* newly_managed_profile) { |
| 249 // Register the ManagementPolicy::Provider before changing the pref when | 303 // Register the ManagementPolicy::Provider before changing the pref when |
| 250 // setting it, and unregister it after changing the pref when clearing it, | 304 // setting it, and unregister it after changing the pref when clearing it, |
| 251 // so pref observers see the correct ManagedMode state. | 305 // so pref observers see the correct ManagedMode state. |
| 252 if (newly_managed_profile) { | 306 bool in_managed_mode = !!newly_managed_profile; |
| 307 if (in_managed_mode) { | |
| 253 DCHECK(!managed_profile_ || managed_profile_ == newly_managed_profile); | 308 DCHECK(!managed_profile_ || managed_profile_ == newly_managed_profile); |
| 254 extensions::ExtensionSystem::Get( | 309 extensions::ExtensionSystem::Get( |
| 255 newly_managed_profile)->management_policy()->RegisterProvider(this); | 310 newly_managed_profile)->management_policy()->RegisterProvider(this); |
| 256 g_browser_process->local_state()->SetBoolean(prefs::kInManagedMode, true); | 311 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, |
| 312 content::Source<Profile>(newly_managed_profile)); | |
| 313 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, | |
| 314 content::Source<Profile>(newly_managed_profile)); | |
| 257 } else { | 315 } else { |
| 258 extensions::ExtensionSystem::Get( | 316 extensions::ExtensionSystem::Get( |
| 259 managed_profile_)->management_policy()->UnregisterProvider(this); | 317 managed_profile_)->management_policy()->UnregisterProvider(this); |
| 260 g_browser_process->local_state()->SetBoolean(prefs::kInManagedMode, false); | 318 registrar_.Remove(this, chrome::NOTIFICATION_EXTENSION_LOADED, |
|
battre
2012/08/14 11:58:33
nit: -2 indent
Bernhard Bauer
2012/08/14 15:36:57
Done.
| |
| 319 content::Source<Profile>(managed_profile_)); | |
| 320 registrar_.Remove(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, | |
| 321 content::Source<Profile>(managed_profile_)); | |
| 261 } | 322 } |
| 323 | |
| 262 managed_profile_ = newly_managed_profile; | 324 managed_profile_ = newly_managed_profile; |
| 325 url_filter_context_->SetActive(in_managed_mode); | |
| 326 g_browser_process->local_state()->SetBoolean(prefs::kInManagedMode, | |
| 327 in_managed_mode); | |
| 328 if (in_managed_mode) | |
| 329 UpdateWhitelist(); | |
| 263 | 330 |
| 264 // This causes the avatar and the profile menu to get updated. | 331 // This causes the avatar and the profile menu to get updated. |
| 265 content::NotificationService::current()->Notify( | 332 content::NotificationService::current()->Notify( |
| 266 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, | 333 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, |
| 267 content::NotificationService::AllBrowserContextsAndSources(), | 334 content::NotificationService::AllBrowserContextsAndSources(), |
| 268 content::NotificationService::NoDetails()); | 335 content::NotificationService::NoDetails()); |
| 269 } | 336 } |
| 337 | |
| 338 void ManagedMode::UpdateWhitelist() { | |
| 339 DCHECK(managed_profile_); | |
| 340 // TODO(bauerb): Update URL filter with whitelist. | |
|
battre
2012/08/14 11:58:33
is this TODO left intentionally?
Bernhard Bauer
2012/08/14 15:36:57
Yes. At the moment the whitelist isn't populated y
| |
| 341 } | |
| OLD | NEW |