| 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_system.h" |
| 9 #include "chrome/browser/prefs/pref_service.h" | 10 #include "chrome/browser/prefs/pref_service.h" |
| 10 #include "chrome/browser/profiles/profile.h" | 11 #include "chrome/browser/profiles/profile.h" |
| 11 #include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h" | 12 #include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h" |
| 12 #include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h" | 13 #include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h" |
| 13 #include "chrome/browser/ui/browser.h" | 14 #include "chrome/browser/ui/browser.h" |
| 14 #include "chrome/browser/ui/browser_window.h" | 15 #include "chrome/browser/ui/browser_window.h" |
| 15 #include "chrome/common/chrome_notification_types.h" | 16 #include "chrome/common/chrome_notification_types.h" |
| 16 #include "chrome/common/chrome_switches.h" | 17 #include "chrome/common/chrome_switches.h" |
| 17 #include "chrome/common/pref_names.h" | 18 #include "chrome/common/pref_names.h" |
| 18 #include "content/public/browser/notification_service.h" | 19 #include "content/public/browser/notification_service.h" |
| 20 #include "grit/generated_resources.h" |
| 21 #include "ui/base/l10n/l10n_util.h" |
| 19 | 22 |
| 20 // static | 23 // static |
| 21 ManagedMode* ManagedMode::GetInstance() { | 24 ManagedMode* ManagedMode::GetInstance() { |
| 22 return Singleton<ManagedMode>::get(); | 25 return Singleton<ManagedMode>::get(); |
| 23 } | 26 } |
| 24 | 27 |
| 25 // static | 28 // static |
| 26 void ManagedMode::RegisterPrefs(PrefService* prefs) { | 29 void ManagedMode::RegisterPrefs(PrefService* prefs) { |
| 27 prefs->RegisterBooleanPref(prefs::kInManagedMode, false); | 30 prefs->RegisterBooleanPref(prefs::kInManagedMode, false); |
| 28 // Set the value directly in the PrefService instead of using | |
| 29 // CommandLinePrefStore so we can change it at runtime. | |
| 30 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoManaged)) | |
| 31 GetInstance()->SetInManagedMode(false); | |
| 32 else if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kManaged)) | |
| 33 GetInstance()->SetInManagedMode(true); | |
| 34 } | 31 } |
| 35 | 32 |
| 36 // static | 33 // static |
| 34 void ManagedMode::Init(Profile* profile) { |
| 35 GetInstance()->InitImpl(profile); |
| 36 } |
| 37 |
| 38 void ManagedMode::InitImpl(Profile* profile) { |
| 39 DCHECK(g_browser_process); |
| 40 DCHECK(g_browser_process->local_state()); |
| 41 |
| 42 Profile* original_profile = profile->GetOriginalProfile(); |
| 43 // Set the value directly in the PrefService instead of using |
| 44 // CommandLinePrefStore so we can change it at runtime. |
| 45 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoManaged)) { |
| 46 SetInManagedMode(NULL); |
| 47 } else if (IsInManagedModeImpl() || |
| 48 CommandLine::ForCurrentProcess()->HasSwitch(switches::kManaged)) { |
| 49 SetInManagedMode(original_profile); |
| 50 } |
| 51 } |
| 52 |
| 53 // static |
| 37 bool ManagedMode::IsInManagedMode() { | 54 bool ManagedMode::IsInManagedMode() { |
| 38 return GetInstance()->IsInManagedModeImpl(); | 55 return GetInstance()->IsInManagedModeImpl(); |
| 39 } | 56 } |
| 40 | 57 |
| 41 bool ManagedMode::IsInManagedModeImpl() { | 58 bool ManagedMode::IsInManagedModeImpl() const { |
| 42 // |g_browser_process| can be NULL during startup. | 59 // |g_browser_process| can be NULL during startup. |
| 43 if (!g_browser_process) | 60 if (!g_browser_process) |
| 44 return false; | 61 return false; |
| 45 // Local State can be NULL during unit tests. | 62 // Local State can be NULL during unit tests. |
| 46 if (!g_browser_process->local_state()) | 63 if (!g_browser_process->local_state()) |
| 47 return false; | 64 return false; |
| 48 return g_browser_process->local_state()->GetBoolean(prefs::kInManagedMode); | 65 return g_browser_process->local_state()->GetBoolean(prefs::kInManagedMode); |
| 49 } | 66 } |
| 50 | 67 |
| 51 // static | 68 // static |
| 52 void ManagedMode::EnterManagedMode(Profile* profile, | 69 void ManagedMode::EnterManagedMode(Profile* profile, |
| 53 const EnterCallback& callback) { | 70 const EnterCallback& callback) { |
| 54 GetInstance()->EnterManagedModeImpl(profile, callback); | 71 GetInstance()->EnterManagedModeImpl(profile, callback); |
| 55 } | 72 } |
| 56 | 73 |
| 57 void ManagedMode::EnterManagedModeImpl(Profile* profile, | 74 void ManagedMode::EnterManagedModeImpl(Profile* profile, |
| 58 const EnterCallback& callback) { | 75 const EnterCallback& callback) { |
| 76 Profile* original_profile = profile->GetOriginalProfile(); |
| 59 if (IsInManagedModeImpl()) { | 77 if (IsInManagedModeImpl()) { |
| 60 callback.Run(true); | 78 callback.Run(original_profile == managed_profile_); |
| 61 return; | 79 return; |
| 62 } | 80 } |
| 63 Profile* original_profile = profile->GetOriginalProfile(); | |
| 64 if (!callbacks_.empty()) { | 81 if (!callbacks_.empty()) { |
| 65 // We are already in the process of entering managed mode, waiting for | 82 // We are already in the process of entering managed mode, waiting for |
| 66 // browsers to close. Don't allow entering managed mode again for a | 83 // browsers to close. Don't allow entering managed mode again for a |
| 67 // different profile, and queue the callback for the same profile. | 84 // different profile, and queue the callback for the same profile. |
| 68 if (original_profile != managed_profile_) | 85 if (original_profile != managed_profile_) |
| 69 callback.Run(false); | 86 callback.Run(false); |
| 70 else | 87 else |
| 71 callbacks_.push_back(callback); | 88 callbacks_.push_back(callback); |
| 72 return; | 89 return; |
| 73 } | 90 } |
| 74 | 91 |
| 75 if (!PlatformConfirmEnter()) { | 92 if (!PlatformConfirmEnter()) { |
| 76 callback.Run(false); | 93 callback.Run(false); |
| 77 return; | 94 return; |
| 78 } | 95 } |
| 79 managed_profile_ = original_profile; | |
| 80 // Close all other profiles. | 96 // Close all other profiles. |
| 81 // At this point, we shouldn't be waiting for other browsers to close (yet). | 97 // At this point, we shouldn't be waiting for other browsers to close (yet). |
| 82 DCHECK_EQ(0u, browsers_to_close_.size()); | 98 DCHECK_EQ(0u, browsers_to_close_.size()); |
| 83 for (BrowserList::const_iterator i = BrowserList::begin(); | 99 for (BrowserList::const_iterator i = BrowserList::begin(); |
| 84 i != BrowserList::end(); ++i) { | 100 i != BrowserList::end(); ++i) { |
| 85 if ((*i)->profile()->GetOriginalProfile() != managed_profile_) | 101 if ((*i)->profile()->GetOriginalProfile() != original_profile) |
| 86 browsers_to_close_.insert(*i); | 102 browsers_to_close_.insert(*i); |
| 87 } | 103 } |
| 88 | 104 |
| 89 if (browsers_to_close_.empty()) { | 105 if (browsers_to_close_.empty()) { |
| 90 SetInManagedMode(true); | 106 SetInManagedMode(original_profile); |
| 91 managed_profile_ = NULL; | |
| 92 callback.Run(true); | 107 callback.Run(true); |
| 93 return; | 108 return; |
| 94 } | 109 } |
| 110 // Remember the profile we're trying to manage while we wait for other |
| 111 // browsers to close. |
| 112 managed_profile_ = original_profile; |
| 95 callbacks_.push_back(callback); | 113 callbacks_.push_back(callback); |
| 96 registrar_.Add(this, content::NOTIFICATION_APP_EXITING, | 114 registrar_.Add(this, content::NOTIFICATION_APP_EXITING, |
| 97 content::NotificationService::AllSources()); | 115 content::NotificationService::AllSources()); |
| 98 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, | 116 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, |
| 99 content::NotificationService::AllSources()); | 117 content::NotificationService::AllSources()); |
| 100 for (std::set<Browser*>::const_iterator i = browsers_to_close_.begin(); | 118 for (std::set<Browser*>::const_iterator i = browsers_to_close_.begin(); |
| 101 i != browsers_to_close_.end(); ++i) { | 119 i != browsers_to_close_.end(); ++i) { |
| 102 (*i)->window()->Close(); | 120 (*i)->window()->Close(); |
| 103 } | 121 } |
| 104 } | 122 } |
| 105 | 123 |
| 106 // static | 124 // static |
| 107 void ManagedMode::LeaveManagedMode() { | 125 void ManagedMode::LeaveManagedMode() { |
| 108 GetInstance()->LeaveManagedModeImpl(); | 126 GetInstance()->LeaveManagedModeImpl(); |
| 109 } | 127 } |
| 110 | 128 |
| 111 void ManagedMode::LeaveManagedModeImpl() { | 129 void ManagedMode::LeaveManagedModeImpl() { |
| 112 bool confirmed = PlatformConfirmLeave(); | 130 bool confirmed = PlatformConfirmLeave(); |
| 113 if (confirmed) | 131 if (confirmed) |
| 114 SetInManagedMode(false); | 132 SetInManagedMode(NULL); |
| 133 } |
| 134 |
| 135 std::string ManagedMode::GetDebugPolicyProviderName() const { |
| 136 // Save the string space in official builds. |
| 137 #ifdef NDEBUG |
| 138 NOTREACHED(); |
| 139 return std::string(); |
| 140 #else |
| 141 return "Managed Mode"; |
| 142 #endif |
| 143 } |
| 144 |
| 145 bool ManagedMode::UserMayLoad(const extensions::Extension* extension, |
| 146 string16* error) const { |
| 147 return ExtensionManagementPolicyImpl(error); |
| 148 } |
| 149 |
| 150 bool ManagedMode::UserMayModifySettings(const extensions::Extension* extension, |
| 151 string16* error) const { |
| 152 return ExtensionManagementPolicyImpl(error); |
| 153 } |
| 154 |
| 155 bool ManagedMode::ExtensionManagementPolicyImpl(string16* error) const { |
| 156 if (!IsInManagedModeImpl()) |
| 157 return true; |
| 158 |
| 159 if (error) |
| 160 *error = l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_MANAGED_MODE); |
| 161 return false; |
| 115 } | 162 } |
| 116 | 163 |
| 117 void ManagedMode::OnBrowserAdded(Browser* browser) { | 164 void ManagedMode::OnBrowserAdded(Browser* browser) { |
| 118 // Return early if we don't have any queued callbacks. | 165 // Return early if we don't have any queued callbacks. |
| 119 if (callbacks_.empty()) | 166 if (callbacks_.empty()) |
| 120 return; | 167 return; |
| 121 | 168 |
| 169 DCHECK(managed_profile_); |
| 122 if (browser->profile()->GetOriginalProfile() != managed_profile_) | 170 if (browser->profile()->GetOriginalProfile() != managed_profile_) |
| 123 FinalizeEnter(false); | 171 FinalizeEnter(false); |
| 124 } | 172 } |
| 125 | 173 |
| 126 void ManagedMode::OnBrowserRemoved(Browser* browser) { | 174 void ManagedMode::OnBrowserRemoved(Browser* browser) { |
| 127 // Return early if we don't have any queued callbacks. | 175 // Return early if we don't have any queued callbacks. |
| 128 if (callbacks_.empty()) | 176 if (callbacks_.empty()) |
| 129 return; | 177 return; |
| 130 | 178 |
| 179 DCHECK(managed_profile_); |
| 131 if (browser->profile()->GetOriginalProfile() == managed_profile_) { | 180 if (browser->profile()->GetOriginalProfile() == managed_profile_) { |
| 132 // Ignore closing browser windows that are in managed mode. | 181 // Ignore closing browser windows that are in managed mode. |
| 133 return; | 182 return; |
| 134 } | 183 } |
| 135 size_t count = browsers_to_close_.erase(browser); | 184 size_t count = browsers_to_close_.erase(browser); |
| 136 DCHECK_EQ(1u, count); | 185 DCHECK_EQ(1u, count); |
| 137 if (browsers_to_close_.empty()) | 186 if (browsers_to_close_.empty()) |
| 138 FinalizeEnter(true); | 187 FinalizeEnter(true); |
| 139 } | 188 } |
| 140 | 189 |
| 141 ManagedMode::ManagedMode() : managed_profile_(NULL) { | 190 ManagedMode::ManagedMode() : managed_profile_(NULL) { |
| 142 BrowserList::AddObserver(this); | 191 BrowserList::AddObserver(this); |
| 143 } | 192 } |
| 144 | 193 |
| 145 ManagedMode::~ManagedMode() { | 194 ManagedMode::~ManagedMode() { |
| 146 BrowserList::RemoveObserver(this); | 195 BrowserList::RemoveObserver(this); |
| 147 DCHECK(!managed_profile_); | |
| 148 DCHECK_EQ(0u, callbacks_.size()); | 196 DCHECK_EQ(0u, callbacks_.size()); |
| 149 DCHECK_EQ(0u, browsers_to_close_.size()); | 197 DCHECK_EQ(0u, browsers_to_close_.size()); |
| 150 } | 198 } |
| 151 | 199 |
| 152 void ManagedMode::Observe(int type, | 200 void ManagedMode::Observe(int type, |
| 153 const content::NotificationSource& source, | 201 const content::NotificationSource& source, |
| 154 const content::NotificationDetails& details) { | 202 const content::NotificationDetails& details) { |
| 155 // Return early if we don't have any queued callbacks. | 203 // Return early if we don't have any queued callbacks. |
| 156 if (callbacks_.empty()) | 204 if (callbacks_.empty()) |
| 157 return; | 205 return; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 169 } | 217 } |
| 170 default: { | 218 default: { |
| 171 NOTREACHED(); | 219 NOTREACHED(); |
| 172 break; | 220 break; |
| 173 } | 221 } |
| 174 } | 222 } |
| 175 } | 223 } |
| 176 | 224 |
| 177 void ManagedMode::FinalizeEnter(bool result) { | 225 void ManagedMode::FinalizeEnter(bool result) { |
| 178 if (result) | 226 if (result) |
| 179 SetInManagedMode(true); | 227 SetInManagedMode(managed_profile_); |
| 180 for (std::vector<EnterCallback>::iterator it = callbacks_.begin(); | 228 for (std::vector<EnterCallback>::iterator it = callbacks_.begin(); |
| 181 it != callbacks_.end(); ++it) { | 229 it != callbacks_.end(); ++it) { |
| 182 it->Run(result); | 230 it->Run(result); |
| 183 } | 231 } |
| 184 managed_profile_ = NULL; | |
| 185 callbacks_.clear(); | 232 callbacks_.clear(); |
| 186 browsers_to_close_.clear(); | 233 browsers_to_close_.clear(); |
| 187 registrar_.RemoveAll(); | 234 registrar_.RemoveAll(); |
| 188 } | 235 } |
| 189 | 236 |
| 190 bool ManagedMode::PlatformConfirmEnter() { | 237 bool ManagedMode::PlatformConfirmEnter() { |
| 191 // TODO(bauerb): Show platform-specific confirmation dialog. | 238 // TODO(bauerb): Show platform-specific confirmation dialog. |
| 192 return true; | 239 return true; |
| 193 } | 240 } |
| 194 | 241 |
| 195 bool ManagedMode::PlatformConfirmLeave() { | 242 bool ManagedMode::PlatformConfirmLeave() { |
| 196 // TODO(bauerb): Show platform-specific confirmation dialog. | 243 // TODO(bauerb): Show platform-specific confirmation dialog. |
| 197 return true; | 244 return true; |
| 198 } | 245 } |
| 199 | 246 |
| 200 void ManagedMode::SetInManagedMode(bool in_managed_mode) { | 247 void ManagedMode::SetInManagedMode(Profile* newly_managed_profile) { |
| 201 g_browser_process->local_state()->SetBoolean(prefs::kInManagedMode, | 248 // Register the ManagementPolicy::Provider before changing the pref when |
| 202 in_managed_mode); | 249 // setting it, and unregister it after changing the pref when clearing it, |
| 250 // so pref observers see the correct ManagedMode state. |
| 251 if (newly_managed_profile) { |
| 252 DCHECK(!managed_profile_ || managed_profile_ == newly_managed_profile); |
| 253 ExtensionSystem::Get( |
| 254 newly_managed_profile)->management_policy()->RegisterProvider(this); |
| 255 g_browser_process->local_state()->SetBoolean(prefs::kInManagedMode, true); |
| 256 } else { |
| 257 ExtensionSystem::Get( |
| 258 managed_profile_)->management_policy()->UnregisterProvider(this); |
| 259 g_browser_process->local_state()->SetBoolean(prefs::kInManagedMode, false); |
| 260 } |
| 261 managed_profile_ = newly_managed_profile; |
| 262 |
| 203 // This causes the avatar and the profile menu to get updated. | 263 // This causes the avatar and the profile menu to get updated. |
| 204 content::NotificationService::current()->Notify( | 264 content::NotificationService::current()->Notify( |
| 205 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, | 265 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, |
| 206 content::NotificationService::AllBrowserContextsAndSources(), | 266 content::NotificationService::AllBrowserContextsAndSources(), |
| 207 content::NotificationService::NoDetails()); | 267 content::NotificationService::NoDetails()); |
| 208 } | 268 } |
| 209 | |
| OLD | NEW |