Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(119)

Side by Side Diff: chrome/browser/managed_mode.cc

Issue 10542023: Disable modifying extensions when in managed mode. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Addressing Bernhard's and Pat's comments Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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_);
Bernhard Bauer 2012/06/19 10:01:36 Does that work for the case where we wait for othe
Pam (message me for reviews) 2012/06/19 12:56:05 Fixed. And the tests didn't catch it because they
253 ExtensionSystem::Get(
254 newly_managed_profile)->management_policy()->RegisterProvider(this);
255 managed_profile_ = newly_managed_profile;
256 g_browser_process->local_state()->SetBoolean(prefs::kInManagedMode, true);
257 } else {
258 ExtensionSystem::Get(
259 managed_profile_)->management_policy()->UnregisterProvider(this);
260 managed_profile_ = NULL;
261 g_browser_process->local_state()->SetBoolean(prefs::kInManagedMode, false);
262 }
263
203 // This causes the avatar and the profile menu to get updated. 264 // This causes the avatar and the profile menu to get updated.
204 content::NotificationService::current()->Notify( 265 content::NotificationService::current()->Notify(
205 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, 266 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED,
206 content::NotificationService::AllBrowserContextsAndSources(), 267 content::NotificationService::AllBrowserContextsAndSources(),
207 content::NotificationService::NoDetails()); 268 content::NotificationService::NoDetails());
208 } 269 }
209
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698