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

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: Improve/fix InitImpl() 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(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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698