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

Side by Side Diff: chrome/browser/chromeos/app_mode/kiosk_app_manager.cc

Issue 14306004: Put Kiosk App parameters into device settings. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase. Created 7 years, 7 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/chromeos/app_mode/kiosk_app_manager.h" 5 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
6 6
7 #include <map> 7 #include <map>
8 #include <set>
8 9
9 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h"
10 #include "base/path_service.h" 13 #include "base/path_service.h"
11 #include "base/prefs/pref_registry_simple.h" 14 #include "base/prefs/pref_registry_simple.h"
12 #include "base/stl_util.h" 15 #include "base/stl_util.h"
13 #include "base/values.h" 16 #include "base/values.h"
14 #include "chrome/browser/chromeos/app_mode/kiosk_app_data.h" 17 #include "chrome/browser/chromeos/app_mode/kiosk_app_data.h"
15 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager_observer.h" 18 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager_observer.h"
19 #include "chrome/browser/chromeos/login/user_manager.h"
16 #include "chrome/browser/chromeos/settings/cros_settings.h" 20 #include "chrome/browser/chromeos/settings/cros_settings.h"
17 #include "chrome/common/chrome_notification_types.h" 21 #include "chrome/common/chrome_notification_types.h"
18 #include "chrome/common/chrome_paths.h" 22 #include "chrome/common/chrome_paths.h"
19 #include "chromeos/cryptohome/async_method_caller.h" 23 #include "chromeos/cryptohome/async_method_caller.h"
20 #include "content/public/browser/notification_details.h"
21 24
22 namespace chromeos { 25 namespace chromeos {
23 26
24 namespace { 27 namespace {
25 28
29 std::string FormatKioskAppUserId(const std::string& app_id) {
30 return app_id + '@' + UserManager::kKioskAppUserDomain;
31 }
32
26 void OnRemoveAppCryptohomeComplete(const std::string& app, 33 void OnRemoveAppCryptohomeComplete(const std::string& app,
27 bool success, 34 bool success,
28 cryptohome::MountError return_code) { 35 cryptohome::MountError return_code) {
29 if (!success) { 36 if (!success) {
30 LOG(ERROR) << "Remove cryptohome for " << app 37 LOG(ERROR) << "Remove cryptohome for " << app
31 << " failed, return code: " << return_code; 38 << " failed, return code: " << return_code;
32 } 39 }
33 } 40 }
34 41
42 // Decodes a device-local account dictionary and extracts the |account_id| and
43 // |app_id| if decoding is successful and the entry refers to a Kiosk App.
44 bool DecodeDeviceLocalAccount(const base::Value* account_spec,
45 std::string* account_id,
46 std::string* app_id) {
47 const base::DictionaryValue* account_dict = NULL;
48 if (!account_spec->GetAsDictionary(&account_dict)) {
49 NOTREACHED();
50 return false;
51 }
52
53 if (!account_dict->GetStringWithoutPathExpansion(
54 kAccountsPrefDeviceLocalAccountsKeyId, account_id)) {
55 LOG(ERROR) << "Account ID missing";
56 return false;
57 }
58
59 int type;
60 if (!account_dict->GetIntegerWithoutPathExpansion(
61 kAccountsPrefDeviceLocalAccountsKeyType, &type) ||
62 type != DEVICE_LOCAL_ACCOUNT_TYPE_KIOSK_APP) {
63 // Not a kiosk app.
64 return false;
65 }
66
67 if (!account_dict->GetStringWithoutPathExpansion(
68 kAccountsPrefDeviceLocalAccountsKeyKioskAppId, app_id)) {
69 LOG(ERROR) << "Kiosk app id missing for " << *account_id;
70 return false;
71 }
72
73 return true;
74 }
75
35 } // namespace 76 } // namespace
36 77
37 // static 78 // static
38 const char KioskAppManager::kKioskDictionaryName[] = "kiosk"; 79 const char KioskAppManager::kKioskDictionaryName[] = "kiosk";
39 const char KioskAppManager::kKeyApps[] = "apps"; 80 const char KioskAppManager::kKeyApps[] = "apps";
40 const char KioskAppManager::kIconCacheDir[] = "kiosk"; 81 const char KioskAppManager::kIconCacheDir[] = "kiosk";
41 82
42 // static 83 // static
43 static base::LazyInstance<KioskAppManager> instance = LAZY_INSTANCE_INITIALIZER; 84 static base::LazyInstance<KioskAppManager> instance = LAZY_INSTANCE_INITIALIZER;
44 KioskAppManager* KioskAppManager::Get() { 85 KioskAppManager* KioskAppManager::Get() {
(...skipping 17 matching lines...) Expand all
62 : id(data.id()), 103 : id(data.id()),
63 name(data.name()), 104 name(data.name()),
64 icon(data.icon()), 105 icon(data.icon()),
65 is_loading(data.IsLoading()) { 106 is_loading(data.IsLoading()) {
66 } 107 }
67 108
68 KioskAppManager::App::App() : is_loading(false) {} 109 KioskAppManager::App::App() : is_loading(false) {}
69 KioskAppManager::App::~App() {} 110 KioskAppManager::App::~App() {}
70 111
71 std::string KioskAppManager::GetAutoLaunchApp() const { 112 std::string KioskAppManager::GetAutoLaunchApp() const {
72 std::string app_id; 113 return auto_launch_app_id_;
73 if (CrosSettings::Get()->GetString(kKioskAutoLaunch, &app_id))
74 return app_id;
75
76 return std::string();
77 } 114 }
78 115
79 void KioskAppManager::SetAutoLaunchApp(const std::string& app_id) { 116 void KioskAppManager::SetAutoLaunchApp(const std::string& app_id) {
80 CrosSettings::Get()->SetString(kKioskAutoLaunch, app_id); 117 CrosSettings::Get()->SetString(kAccountsPrefDeviceLocalAccountAutoLoginId,
118 FormatKioskAppUserId(app_id));
119 CrosSettings::Get()->SetInteger(kAccountsPrefDeviceLocalAccountAutoLoginDelay,
120 0);
81 } 121 }
82 122
83 void KioskAppManager::AddApp(const std::string& app_id) { 123 void KioskAppManager::AddApp(const std::string& app_id) {
84 base::StringValue value(app_id); 124 CrosSettings* cros_settings = CrosSettings::Get();
85 CrosSettings::Get()->AppendToList(kKioskApps, &value); 125 const base::ListValue* accounts_list = NULL;
126 cros_settings->GetList(kAccountsPrefDeviceLocalAccounts, &accounts_list);
127
128 // Don't insert if the app if it's already in the list.
129 base::ListValue new_accounts_list;
130 for (base::ListValue::const_iterator entry(accounts_list->begin());
131 entry != accounts_list->end(); ++entry) {
132 std::string account_id;
133 std::string kiosk_app_id;
134 if (DecodeDeviceLocalAccount(*entry, &account_id, &kiosk_app_id) &&
135 kiosk_app_id == app_id) {
136 return;
137 }
138 new_accounts_list.Append((*entry)->DeepCopy());
139 }
140
141 // Add the new account.
142 scoped_ptr<base::DictionaryValue> new_entry(new base::DictionaryValue());
143 new_entry->SetStringWithoutPathExpansion(
144 kAccountsPrefDeviceLocalAccountsKeyId, FormatKioskAppUserId(app_id));
145 new_entry->SetIntegerWithoutPathExpansion(
146 kAccountsPrefDeviceLocalAccountsKeyType,
147 DEVICE_LOCAL_ACCOUNT_TYPE_KIOSK_APP);
148 new_entry->SetStringWithoutPathExpansion(
149 kAccountsPrefDeviceLocalAccountsKeyKioskAppId, app_id);
150 new_accounts_list.Append(new_entry.release());
151 cros_settings->Set(kAccountsPrefDeviceLocalAccounts, new_accounts_list);
86 } 152 }
87 153
88 void KioskAppManager::RemoveApp(const std::string& app_id) { 154 void KioskAppManager::RemoveApp(const std::string& app_id) {
89 base::StringValue value(app_id); 155 CrosSettings* cros_settings = CrosSettings::Get();
90 CrosSettings::Get()->RemoveFromList(kKioskApps, &value); 156 const base::ListValue* accounts_list = NULL;
157 cros_settings->GetList(kAccountsPrefDeviceLocalAccounts, &accounts_list);
158
159 // Duplicate the list, filtering out entries that match |app_id|.
160 base::ListValue new_accounts_list;
161 for (base::ListValue::const_iterator entry(accounts_list->begin());
162 entry != accounts_list->end(); ++entry) {
163 std::string account_id;
164 std::string kiosk_app_id;
165 if (DecodeDeviceLocalAccount(*entry, &account_id, &kiosk_app_id) &&
166 kiosk_app_id == app_id) {
167 continue;
168 }
169 new_accounts_list.Append((*entry)->DeepCopy());
170 }
171
172 cros_settings->Set(kAccountsPrefDeviceLocalAccounts, new_accounts_list);
91 } 173 }
92 174
93 void KioskAppManager::GetApps(Apps* apps) const { 175 void KioskAppManager::GetApps(Apps* apps) const {
94 apps->reserve(apps_.size()); 176 apps->reserve(apps_.size());
95 for (size_t i = 0; i < apps_.size(); ++i) 177 for (size_t i = 0; i < apps_.size(); ++i)
96 apps->push_back(App(*apps_[i])); 178 apps->push_back(App(*apps_[i]));
97 } 179 }
98 180
99 bool KioskAppManager::GetApp(const std::string& app_id, App* app) const { 181 bool KioskAppManager::GetApp(const std::string& app_id, App* app) const {
100 const KioskAppData* data = GetAppData(app_id); 182 const KioskAppData* data = GetAppData(app_id);
101 if (!data) 183 if (!data)
102 return false; 184 return false;
103 185
104 *app = App(*data); 186 *app = App(*data);
105 return true; 187 return true;
106 } 188 }
107 189
108 const base::RefCountedString* KioskAppManager::GetAppRawIcon( 190 const base::RefCountedString* KioskAppManager::GetAppRawIcon(
109 const std::string& app_id) const { 191 const std::string& app_id) const {
110 const KioskAppData* data = GetAppData(app_id); 192 const KioskAppData* data = GetAppData(app_id);
111 if (!data) 193 if (!data)
112 return NULL; 194 return NULL;
113 195
114 return data->raw_icon(); 196 return data->raw_icon();
115 } 197 }
116 198
117 bool KioskAppManager::GetDisableBailoutShortcut() const { 199 bool KioskAppManager::GetDisableBailoutShortcut() const {
118 bool disable; 200 bool enable;
119 if (CrosSettings::Get()->GetBoolean(kKioskDisableBailoutShortcut, &disable)) 201 if (CrosSettings::Get()->GetBoolean(
120 return disable; 202 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled, &enable)) {
203 return !enable;
204 }
121 205
122 return false; 206 return false;
123 } 207 }
124 208
125 void KioskAppManager::AddObserver(KioskAppManagerObserver* observer) { 209 void KioskAppManager::AddObserver(KioskAppManagerObserver* observer) {
126 observers_.AddObserver(observer); 210 observers_.AddObserver(observer);
127 } 211 }
128 212
129 void KioskAppManager::RemoveObserver(KioskAppManagerObserver* observer) { 213 void KioskAppManager::RemoveObserver(KioskAppManagerObserver* observer) {
130 observers_.RemoveObserver(observer); 214 observers_.RemoveObserver(observer);
131 } 215 }
132 216
133 KioskAppManager::KioskAppManager() { 217 KioskAppManager::KioskAppManager() {
134 UpdateAppData(); 218 UpdateAppData();
135 CrosSettings::Get()->AddSettingsObserver(kKioskApps, this); 219 CrosSettings::Get()->AddSettingsObserver(
220 kAccountsPrefDeviceLocalAccounts, this);
221 CrosSettings::Get()->AddSettingsObserver(
222 kAccountsPrefDeviceLocalAccountAutoLoginId, this);
136 } 223 }
137 224
138 KioskAppManager::~KioskAppManager() {} 225 KioskAppManager::~KioskAppManager() {}
139 226
140 void KioskAppManager::CleanUp() { 227 void KioskAppManager::CleanUp() {
141 CrosSettings::Get()->RemoveSettingsObserver(kKioskApps, this); 228 CrosSettings::Get()->RemoveSettingsObserver(
229 kAccountsPrefDeviceLocalAccounts, this);
230 CrosSettings::Get()->RemoveSettingsObserver(
231 kAccountsPrefDeviceLocalAccountAutoLoginId, this);
142 apps_.clear(); 232 apps_.clear();
143 } 233 }
144 234
145 const KioskAppData* KioskAppManager::GetAppData( 235 const KioskAppData* KioskAppManager::GetAppData(
146 const std::string& app_id) const { 236 const std::string& app_id) const {
147 for (size_t i = 0; i < apps_.size(); ++i) { 237 for (size_t i = 0; i < apps_.size(); ++i) {
148 const KioskAppData* data = apps_[i]; 238 const KioskAppData* data = apps_[i];
149 if (data->id() == app_id) 239 if (data->id() == app_id)
150 return data; 240 return data;
151 } 241 }
152 242
153 return NULL; 243 return NULL;
154 } 244 }
155 245
156 void KioskAppManager::UpdateAppData() { 246 void KioskAppManager::UpdateAppData() {
157 // Gets app id to data mapping for existing apps. 247 // Gets app id to data mapping for existing apps.
158 std::map<std::string, KioskAppData*> old_apps; 248 std::map<std::string, KioskAppData*> old_apps;
159 for (size_t i = 0; i < apps_.size(); ++i) 249 for (size_t i = 0; i < apps_.size(); ++i)
160 old_apps[apps_[i]->id()] = apps_[i]; 250 old_apps[apps_[i]->id()] = apps_[i];
161 apps_.weak_clear(); // |old_apps| takes ownership 251 apps_.weak_clear(); // |old_apps| takes ownership
162 252
163 const base::ListValue* new_apps; 253 auto_launch_app_id_.clear();
164 CHECK(CrosSettings::Get()->GetList(kKioskApps, &new_apps)); 254 std::string auto_login_account_id_;
bartfab (slow) 2013/04/26 12:34:59 Nit: Remove trailing underscore.
Mattias Nissler (ping if slow) 2013/04/26 13:44:46 Done.
255 CrosSettings::Get()->GetString(kAccountsPrefDeviceLocalAccountAutoLoginId,
256 &auto_login_account_id_);
165 257
166 // Re-populates |apps_| and reuses existing KioskAppData when possible. 258 const base::ListValue* local_accounts;
167 for (base::ListValue::const_iterator new_it = new_apps->begin(); 259 if (CrosSettings::Get()->GetList(kAccountsPrefDeviceLocalAccounts,
bartfab (slow) 2013/04/26 12:34:59 Nit: This is a bit inconsistent: In some places, e
Mattias Nissler (ping if slow) 2013/04/26 13:44:46 Fixed the other two call sites.
168 new_it != new_apps->end(); 260 &local_accounts)) {
169 ++new_it) { 261 // Re-populates |apps_| and reuses existing KioskAppData when possible.
170 std::string id; 262 for (base::ListValue::const_iterator account(local_accounts->begin());
171 CHECK((*new_it)->GetAsString(&id)); 263 account != local_accounts->end(); ++account) {
264 std::string account_id;
265 std::string kiosk_app_id;
266 if (!DecodeDeviceLocalAccount(*account, &account_id, &kiosk_app_id))
267 continue;
172 268
173 std::map<std::string, KioskAppData*>::iterator old_it = old_apps.find(id); 269 if (account_id == auto_login_account_id_)
174 if (old_it != old_apps.end()) { 270 auto_launch_app_id_ = kiosk_app_id;
175 apps_.push_back(old_it->second); 271
176 old_apps.erase(old_it); 272 // TODO(mnissler): Support non-CWS update URLs.
177 } else { 273
178 KioskAppData* new_app = new KioskAppData(this, id); 274 std::map<std::string, KioskAppData*>::iterator old_it =
179 apps_.push_back(new_app); // Takes ownership of |new_app|. 275 old_apps.find(kiosk_app_id);
180 new_app->Load(); 276 if (old_it != old_apps.end()) {
277 apps_.push_back(old_it->second);
278 old_apps.erase(old_it);
279 } else {
280 KioskAppData* new_app = new KioskAppData(this, kiosk_app_id);
281 apps_.push_back(new_app); // Takes ownership of |new_app|.
282 new_app->Load();
283 }
181 } 284 }
182 } 285 }
183 286
184 // Clears cache and deletes the remaining old data. 287 // Clears cache and deletes the remaining old data.
185 for (std::map<std::string, KioskAppData*>::iterator it = old_apps.begin(); 288 for (std::map<std::string, KioskAppData*>::iterator it = old_apps.begin();
186 it != old_apps.end(); ++it) { 289 it != old_apps.end(); ++it) {
187 it->second->ClearCache(); 290 it->second->ClearCache();
188 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( 291 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
189 it->first, base::Bind(&OnRemoveAppCryptohomeComplete, it->first)); 292 it->first, base::Bind(&OnRemoveAppCryptohomeComplete, it->first));
190 } 293 }
191 STLDeleteValues(&old_apps); 294 STLDeleteValues(&old_apps);
295
296 FOR_EACH_OBSERVER(KioskAppManagerObserver, observers_,
297 OnKioskAppsListChanged());
192 } 298 }
193 299
194 void KioskAppManager::Observe(int type, 300 void KioskAppManager::Observe(int type,
195 const content::NotificationSource& source, 301 const content::NotificationSource& source,
196 const content::NotificationDetails& details) { 302 const content::NotificationDetails& details) {
197 DCHECK_EQ(chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED, type); 303 DCHECK_EQ(chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED, type);
198 DCHECK_EQ(kKioskApps,
199 *content::Details<const std::string>(details).ptr());
200
201 UpdateAppData(); 304 UpdateAppData();
202 } 305 }
203 306
204 void KioskAppManager::GetKioskAppIconCacheDir(base::FilePath* cache_dir) { 307 void KioskAppManager::GetKioskAppIconCacheDir(base::FilePath* cache_dir) {
205 base::FilePath user_data_dir; 308 base::FilePath user_data_dir;
206 CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)); 309 CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
207 *cache_dir = user_data_dir.AppendASCII(kIconCacheDir); 310 *cache_dir = user_data_dir.AppendASCII(kIconCacheDir);
208 } 311 }
209 312
210 void KioskAppManager::OnKioskAppDataChanged(const std::string& app_id) { 313 void KioskAppManager::OnKioskAppDataChanged(const std::string& app_id) {
211 FOR_EACH_OBSERVER(KioskAppManagerObserver, 314 FOR_EACH_OBSERVER(KioskAppManagerObserver,
212 observers_, 315 observers_,
213 OnKioskAppDataChanged(app_id)); 316 OnKioskAppDataChanged(app_id));
214 } 317 }
215 318
216 void KioskAppManager::OnKioskAppDataLoadFailure(const std::string& app_id) { 319 void KioskAppManager::OnKioskAppDataLoadFailure(const std::string& app_id) {
217 FOR_EACH_OBSERVER(KioskAppManagerObserver, 320 FOR_EACH_OBSERVER(KioskAppManagerObserver,
218 observers_, 321 observers_,
219 OnKioskAppDataLoadFailure(app_id)); 322 OnKioskAppDataLoadFailure(app_id));
220 RemoveApp(app_id); 323 RemoveApp(app_id);
221 } 324 }
222 325
223 } // namespace chromeos 326 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/app_mode/kiosk_app_manager.h ('k') | chrome/browser/chromeos/app_mode/kiosk_app_manager_observer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698