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(false, NULL); | |
47 } else if (IsInManagedModeImpl() || | |
48 CommandLine::ForCurrentProcess()->HasSwitch(switches::kManaged)) { | |
49 SetInManagedMode(true, 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(true, 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(false, NULL); |
133 } | |
134 | |
135 std::string ManagedMode::GetDebugPolicyProviderName() const { | |
136 return "Managed Mode"; | |
Bernhard Bauer
2012/06/18 13:41:06
Is the compiler smart enough to strip this out if
| |
137 } | |
138 | |
139 bool ManagedMode::UserMayLoad(const extensions::Extension* extension, | |
140 string16* error) const { | |
141 return ExtensionManagementPolicyImpl(error); | |
142 } | |
143 | |
144 bool ManagedMode::UserMayModifySettings(const extensions::Extension* extension, | |
145 string16* error) const { | |
146 return ExtensionManagementPolicyImpl(error); | |
147 } | |
148 | |
149 bool ManagedMode::ExtensionManagementPolicyImpl(string16* error) const { | |
150 if (!IsInManagedModeImpl()) | |
151 return true; | |
152 | |
153 if (error) | |
154 *error = l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_MANAGED_MODE); | |
155 return false; | |
115 } | 156 } |
116 | 157 |
117 void ManagedMode::OnBrowserAdded(Browser* browser) { | 158 void ManagedMode::OnBrowserAdded(Browser* browser) { |
118 // Return early if we don't have any queued callbacks. | 159 // Return early if we don't have any queued callbacks. |
119 if (callbacks_.empty()) | 160 if (callbacks_.empty()) |
120 return; | 161 return; |
121 | 162 |
163 DCHECK(managed_profile_); | |
122 if (browser->profile()->GetOriginalProfile() != managed_profile_) | 164 if (browser->profile()->GetOriginalProfile() != managed_profile_) |
123 FinalizeEnter(false); | 165 FinalizeEnter(false); |
124 } | 166 } |
125 | 167 |
126 void ManagedMode::OnBrowserRemoved(Browser* browser) { | 168 void ManagedMode::OnBrowserRemoved(Browser* browser) { |
127 // Return early if we don't have any queued callbacks. | 169 // Return early if we don't have any queued callbacks. |
128 if (callbacks_.empty()) | 170 if (callbacks_.empty()) |
129 return; | 171 return; |
130 | 172 |
173 DCHECK(managed_profile_); | |
131 if (browser->profile()->GetOriginalProfile() == managed_profile_) { | 174 if (browser->profile()->GetOriginalProfile() == managed_profile_) { |
132 // Ignore closing browser windows that are in managed mode. | 175 // Ignore closing browser windows that are in managed mode. |
133 return; | 176 return; |
134 } | 177 } |
135 size_t count = browsers_to_close_.erase(browser); | 178 size_t count = browsers_to_close_.erase(browser); |
136 DCHECK_EQ(1u, count); | 179 DCHECK_EQ(1u, count); |
137 if (browsers_to_close_.empty()) | 180 if (browsers_to_close_.empty()) |
138 FinalizeEnter(true); | 181 FinalizeEnter(true); |
139 } | 182 } |
140 | 183 |
141 ManagedMode::ManagedMode() : managed_profile_(NULL) { | 184 ManagedMode::ManagedMode() : managed_profile_(NULL) { |
142 BrowserList::AddObserver(this); | 185 BrowserList::AddObserver(this); |
143 } | 186 } |
144 | 187 |
145 ManagedMode::~ManagedMode() { | 188 ManagedMode::~ManagedMode() { |
146 BrowserList::RemoveObserver(this); | 189 BrowserList::RemoveObserver(this); |
147 DCHECK(!managed_profile_); | |
148 DCHECK_EQ(0u, callbacks_.size()); | 190 DCHECK_EQ(0u, callbacks_.size()); |
149 DCHECK_EQ(0u, browsers_to_close_.size()); | 191 DCHECK_EQ(0u, browsers_to_close_.size()); |
150 } | 192 } |
151 | 193 |
152 void ManagedMode::Observe(int type, | 194 void ManagedMode::Observe(int type, |
153 const content::NotificationSource& source, | 195 const content::NotificationSource& source, |
154 const content::NotificationDetails& details) { | 196 const content::NotificationDetails& details) { |
155 // Return early if we don't have any queued callbacks. | 197 // Return early if we don't have any queued callbacks. |
156 if (callbacks_.empty()) | 198 if (callbacks_.empty()) |
157 return; | 199 return; |
(...skipping 11 matching lines...) Expand all Loading... | |
169 } | 211 } |
170 default: { | 212 default: { |
171 NOTREACHED(); | 213 NOTREACHED(); |
172 break; | 214 break; |
173 } | 215 } |
174 } | 216 } |
175 } | 217 } |
176 | 218 |
177 void ManagedMode::FinalizeEnter(bool result) { | 219 void ManagedMode::FinalizeEnter(bool result) { |
178 if (result) | 220 if (result) |
179 SetInManagedMode(true); | 221 SetInManagedMode(true, managed_profile_); |
180 for (std::vector<EnterCallback>::iterator it = callbacks_.begin(); | 222 for (std::vector<EnterCallback>::iterator it = callbacks_.begin(); |
181 it != callbacks_.end(); ++it) { | 223 it != callbacks_.end(); ++it) { |
182 it->Run(result); | 224 it->Run(result); |
183 } | 225 } |
184 managed_profile_ = NULL; | |
185 callbacks_.clear(); | 226 callbacks_.clear(); |
186 browsers_to_close_.clear(); | 227 browsers_to_close_.clear(); |
187 registrar_.RemoveAll(); | 228 registrar_.RemoveAll(); |
188 } | 229 } |
189 | 230 |
190 bool ManagedMode::PlatformConfirmEnter() { | 231 bool ManagedMode::PlatformConfirmEnter() { |
191 // TODO(bauerb): Show platform-specific confirmation dialog. | 232 // TODO(bauerb): Show platform-specific confirmation dialog. |
192 return true; | 233 return true; |
193 } | 234 } |
194 | 235 |
195 bool ManagedMode::PlatformConfirmLeave() { | 236 bool ManagedMode::PlatformConfirmLeave() { |
196 // TODO(bauerb): Show platform-specific confirmation dialog. | 237 // TODO(bauerb): Show platform-specific confirmation dialog. |
197 return true; | 238 return true; |
198 } | 239 } |
199 | 240 |
200 void ManagedMode::SetInManagedMode(bool in_managed_mode) { | 241 void ManagedMode::SetInManagedMode(bool in_managed_mode, |
242 Profile* newly_managed_profile) { | |
243 // Register the ManagementPolicy::Provider before changing the pref when | |
244 // setting it, and unregister it after changing the pref when clearing it, | |
245 // so pref observers see the correct ManagedMode state. | |
246 if (in_managed_mode) { | |
247 CHECK(newly_managed_profile); | |
248 ExtensionSystem::Get( | |
249 newly_managed_profile)->management_policy()->RegisterProvider(this); | |
250 managed_profile_ = newly_managed_profile; | |
251 } | |
201 g_browser_process->local_state()->SetBoolean(prefs::kInManagedMode, | 252 g_browser_process->local_state()->SetBoolean(prefs::kInManagedMode, |
202 in_managed_mode); | 253 in_managed_mode); |
254 if (!in_managed_mode) { | |
255 ExtensionSystem::Get( | |
256 managed_profile_)->management_policy()->UnregisterProvider(this); | |
257 managed_profile_ = NULL; | |
258 } | |
259 | |
203 // This causes the avatar and the profile menu to get updated. | 260 // This causes the avatar and the profile menu to get updated. |
204 content::NotificationService::current()->Notify( | 261 content::NotificationService::current()->Notify( |
205 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, | 262 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, |
206 content::NotificationService::AllBrowserContextsAndSources(), | 263 content::NotificationService::AllBrowserContextsAndSources(), |
207 content::NotificationService::NoDetails()); | 264 content::NotificationService::NoDetails()); |
208 } | 265 } |
209 | |
OLD | NEW |