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

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(
118 kAccountsPrefDeviceLocalAccountAutoLoginId,
119 app_id.empty() ? std::string() : FormatKioskAppUserId(app_id));
120 CrosSettings::Get()->SetInteger(
121 kAccountsPrefDeviceLocalAccountAutoLoginDelay, 0);
81 } 122 }
82 123
83 void KioskAppManager::AddApp(const std::string& app_id) { 124 void KioskAppManager::AddApp(const std::string& app_id) {
84 base::StringValue value(app_id); 125 CrosSettings* cros_settings = CrosSettings::Get();
85 CrosSettings::Get()->AppendToList(kKioskApps, &value); 126 const base::ListValue* accounts_list = NULL;
127 cros_settings->GetList(kAccountsPrefDeviceLocalAccounts, &accounts_list);
128
129 // Don't insert if the app if it's already in the list.
130 base::ListValue new_accounts_list;
131 if (accounts_list) {
132 for (base::ListValue::const_iterator entry(accounts_list->begin());
133 entry != accounts_list->end(); ++entry) {
134 std::string account_id;
135 std::string kiosk_app_id;
136 if (DecodeDeviceLocalAccount(*entry, &account_id, &kiosk_app_id) &&
137 kiosk_app_id == app_id) {
138 return;
139 }
140 new_accounts_list.Append((*entry)->DeepCopy());
141 }
142 }
143
144 // Add the new account.
145 scoped_ptr<base::DictionaryValue> new_entry(new base::DictionaryValue());
146 new_entry->SetStringWithoutPathExpansion(
147 kAccountsPrefDeviceLocalAccountsKeyId, FormatKioskAppUserId(app_id));
148 new_entry->SetIntegerWithoutPathExpansion(
149 kAccountsPrefDeviceLocalAccountsKeyType,
150 DEVICE_LOCAL_ACCOUNT_TYPE_KIOSK_APP);
151 new_entry->SetStringWithoutPathExpansion(
152 kAccountsPrefDeviceLocalAccountsKeyKioskAppId, app_id);
153 new_accounts_list.Append(new_entry.release());
154 cros_settings->Set(kAccountsPrefDeviceLocalAccounts, new_accounts_list);
86 } 155 }
87 156
88 void KioskAppManager::RemoveApp(const std::string& app_id) { 157 void KioskAppManager::RemoveApp(const std::string& app_id) {
89 base::StringValue value(app_id); 158 CrosSettings* cros_settings = CrosSettings::Get();
90 CrosSettings::Get()->RemoveFromList(kKioskApps, &value); 159 const base::ListValue* accounts_list = NULL;
160 cros_settings->GetList(kAccountsPrefDeviceLocalAccounts, &accounts_list);
161 if (!accounts_list)
162 return;
163
164 // Duplicate the list, filtering out entries that match |app_id|.
165 base::ListValue new_accounts_list;
166 for (base::ListValue::const_iterator entry(accounts_list->begin());
167 entry != accounts_list->end(); ++entry) {
168 std::string account_id;
169 std::string kiosk_app_id;
170 if (DecodeDeviceLocalAccount(*entry, &account_id, &kiosk_app_id) &&
171 kiosk_app_id == app_id) {
172 continue;
173 }
174 new_accounts_list.Append((*entry)->DeepCopy());
175 }
176
177 cros_settings->Set(kAccountsPrefDeviceLocalAccounts, new_accounts_list);
91 } 178 }
92 179
93 void KioskAppManager::GetApps(Apps* apps) const { 180 void KioskAppManager::GetApps(Apps* apps) const {
94 apps->reserve(apps_.size()); 181 apps->reserve(apps_.size());
95 for (size_t i = 0; i < apps_.size(); ++i) 182 for (size_t i = 0; i < apps_.size(); ++i)
96 apps->push_back(App(*apps_[i])); 183 apps->push_back(App(*apps_[i]));
97 } 184 }
98 185
99 bool KioskAppManager::GetApp(const std::string& app_id, App* app) const { 186 bool KioskAppManager::GetApp(const std::string& app_id, App* app) const {
100 const KioskAppData* data = GetAppData(app_id); 187 const KioskAppData* data = GetAppData(app_id);
101 if (!data) 188 if (!data)
102 return false; 189 return false;
103 190
104 *app = App(*data); 191 *app = App(*data);
105 return true; 192 return true;
106 } 193 }
107 194
108 const base::RefCountedString* KioskAppManager::GetAppRawIcon( 195 const base::RefCountedString* KioskAppManager::GetAppRawIcon(
109 const std::string& app_id) const { 196 const std::string& app_id) const {
110 const KioskAppData* data = GetAppData(app_id); 197 const KioskAppData* data = GetAppData(app_id);
111 if (!data) 198 if (!data)
112 return NULL; 199 return NULL;
113 200
114 return data->raw_icon(); 201 return data->raw_icon();
115 } 202 }
116 203
117 bool KioskAppManager::GetDisableBailoutShortcut() const { 204 bool KioskAppManager::GetDisableBailoutShortcut() const {
118 bool disable; 205 bool enable;
119 if (CrosSettings::Get()->GetBoolean(kKioskDisableBailoutShortcut, &disable)) 206 if (CrosSettings::Get()->GetBoolean(
120 return disable; 207 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled, &enable)) {
208 return !enable;
209 }
121 210
122 return false; 211 return false;
123 } 212 }
124 213
125 void KioskAppManager::AddObserver(KioskAppManagerObserver* observer) { 214 void KioskAppManager::AddObserver(KioskAppManagerObserver* observer) {
126 observers_.AddObserver(observer); 215 observers_.AddObserver(observer);
127 } 216 }
128 217
129 void KioskAppManager::RemoveObserver(KioskAppManagerObserver* observer) { 218 void KioskAppManager::RemoveObserver(KioskAppManagerObserver* observer) {
130 observers_.RemoveObserver(observer); 219 observers_.RemoveObserver(observer);
131 } 220 }
132 221
133 KioskAppManager::KioskAppManager() { 222 KioskAppManager::KioskAppManager() {
134 UpdateAppData(); 223 UpdateAppData();
135 CrosSettings::Get()->AddSettingsObserver(kKioskApps, this); 224 CrosSettings::Get()->AddSettingsObserver(
225 kAccountsPrefDeviceLocalAccounts, this);
226 CrosSettings::Get()->AddSettingsObserver(
227 kAccountsPrefDeviceLocalAccountAutoLoginId, this);
136 } 228 }
137 229
138 KioskAppManager::~KioskAppManager() {} 230 KioskAppManager::~KioskAppManager() {}
139 231
140 void KioskAppManager::CleanUp() { 232 void KioskAppManager::CleanUp() {
141 CrosSettings::Get()->RemoveSettingsObserver(kKioskApps, this); 233 CrosSettings::Get()->RemoveSettingsObserver(
234 kAccountsPrefDeviceLocalAccounts, this);
235 CrosSettings::Get()->RemoveSettingsObserver(
236 kAccountsPrefDeviceLocalAccountAutoLoginId, this);
142 apps_.clear(); 237 apps_.clear();
143 } 238 }
144 239
145 const KioskAppData* KioskAppManager::GetAppData( 240 const KioskAppData* KioskAppManager::GetAppData(
146 const std::string& app_id) const { 241 const std::string& app_id) const {
147 for (size_t i = 0; i < apps_.size(); ++i) { 242 for (size_t i = 0; i < apps_.size(); ++i) {
148 const KioskAppData* data = apps_[i]; 243 const KioskAppData* data = apps_[i];
149 if (data->id() == app_id) 244 if (data->id() == app_id)
150 return data; 245 return data;
151 } 246 }
152 247
153 return NULL; 248 return NULL;
154 } 249 }
155 250
156 void KioskAppManager::UpdateAppData() { 251 void KioskAppManager::UpdateAppData() {
157 // Gets app id to data mapping for existing apps. 252 // Gets app id to data mapping for existing apps.
158 std::map<std::string, KioskAppData*> old_apps; 253 std::map<std::string, KioskAppData*> old_apps;
159 for (size_t i = 0; i < apps_.size(); ++i) 254 for (size_t i = 0; i < apps_.size(); ++i)
160 old_apps[apps_[i]->id()] = apps_[i]; 255 old_apps[apps_[i]->id()] = apps_[i];
161 apps_.weak_clear(); // |old_apps| takes ownership 256 apps_.weak_clear(); // |old_apps| takes ownership
162 257
163 const base::ListValue* new_apps; 258 auto_launch_app_id_.clear();
164 CHECK(CrosSettings::Get()->GetList(kKioskApps, &new_apps)); 259 std::string auto_login_account_id;
260 CrosSettings::Get()->GetString(kAccountsPrefDeviceLocalAccountAutoLoginId,
261 &auto_login_account_id);
165 262
166 // Re-populates |apps_| and reuses existing KioskAppData when possible. 263 const base::ListValue* local_accounts;
167 for (base::ListValue::const_iterator new_it = new_apps->begin(); 264 if (CrosSettings::Get()->GetList(kAccountsPrefDeviceLocalAccounts,
168 new_it != new_apps->end(); 265 &local_accounts)) {
169 ++new_it) { 266 // Re-populates |apps_| and reuses existing KioskAppData when possible.
170 std::string id; 267 for (base::ListValue::const_iterator account(local_accounts->begin());
171 CHECK((*new_it)->GetAsString(&id)); 268 account != local_accounts->end(); ++account) {
269 std::string account_id;
270 std::string kiosk_app_id;
271 if (!DecodeDeviceLocalAccount(*account, &account_id, &kiosk_app_id))
272 continue;
172 273
173 std::map<std::string, KioskAppData*>::iterator old_it = old_apps.find(id); 274 if (account_id == auto_login_account_id)
174 if (old_it != old_apps.end()) { 275 auto_launch_app_id_ = kiosk_app_id;
175 apps_.push_back(old_it->second); 276
176 old_apps.erase(old_it); 277 // TODO(mnissler): Support non-CWS update URLs.
177 } else { 278
178 KioskAppData* new_app = new KioskAppData(this, id); 279 std::map<std::string, KioskAppData*>::iterator old_it =
179 apps_.push_back(new_app); // Takes ownership of |new_app|. 280 old_apps.find(kiosk_app_id);
180 new_app->Load(); 281 if (old_it != old_apps.end()) {
282 apps_.push_back(old_it->second);
283 old_apps.erase(old_it);
284 } else {
285 KioskAppData* new_app = new KioskAppData(this, kiosk_app_id);
286 apps_.push_back(new_app); // Takes ownership of |new_app|.
287 new_app->Load();
288 }
181 } 289 }
182 } 290 }
183 291
184 // Clears cache and deletes the remaining old data. 292 // Clears cache and deletes the remaining old data.
185 for (std::map<std::string, KioskAppData*>::iterator it = old_apps.begin(); 293 for (std::map<std::string, KioskAppData*>::iterator it = old_apps.begin();
186 it != old_apps.end(); ++it) { 294 it != old_apps.end(); ++it) {
187 it->second->ClearCache(); 295 it->second->ClearCache();
188 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( 296 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
189 it->first, base::Bind(&OnRemoveAppCryptohomeComplete, it->first)); 297 it->first, base::Bind(&OnRemoveAppCryptohomeComplete, it->first));
190 } 298 }
191 STLDeleteValues(&old_apps); 299 STLDeleteValues(&old_apps);
300
301 FOR_EACH_OBSERVER(KioskAppManagerObserver, observers_,
302 OnKioskAppsSettingsChanged());
192 } 303 }
193 304
194 void KioskAppManager::Observe(int type, 305 void KioskAppManager::Observe(int type,
195 const content::NotificationSource& source, 306 const content::NotificationSource& source,
196 const content::NotificationDetails& details) { 307 const content::NotificationDetails& details) {
197 DCHECK_EQ(chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED, type); 308 DCHECK_EQ(chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED, type);
198 DCHECK_EQ(kKioskApps,
199 *content::Details<const std::string>(details).ptr());
200
201 UpdateAppData(); 309 UpdateAppData();
202 } 310 }
203 311
204 void KioskAppManager::GetKioskAppIconCacheDir(base::FilePath* cache_dir) { 312 void KioskAppManager::GetKioskAppIconCacheDir(base::FilePath* cache_dir) {
205 base::FilePath user_data_dir; 313 base::FilePath user_data_dir;
206 CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)); 314 CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
207 *cache_dir = user_data_dir.AppendASCII(kIconCacheDir); 315 *cache_dir = user_data_dir.AppendASCII(kIconCacheDir);
208 } 316 }
209 317
210 void KioskAppManager::OnKioskAppDataChanged(const std::string& app_id) { 318 void KioskAppManager::OnKioskAppDataChanged(const std::string& app_id) {
211 FOR_EACH_OBSERVER(KioskAppManagerObserver, 319 FOR_EACH_OBSERVER(KioskAppManagerObserver,
212 observers_, 320 observers_,
213 OnKioskAppDataChanged(app_id)); 321 OnKioskAppDataChanged(app_id));
214 } 322 }
215 323
216 void KioskAppManager::OnKioskAppDataLoadFailure(const std::string& app_id) { 324 void KioskAppManager::OnKioskAppDataLoadFailure(const std::string& app_id) {
217 FOR_EACH_OBSERVER(KioskAppManagerObserver, 325 FOR_EACH_OBSERVER(KioskAppManagerObserver,
218 observers_, 326 observers_,
219 OnKioskAppDataLoadFailure(app_id)); 327 OnKioskAppDataLoadFailure(app_id));
220 RemoveApp(app_id); 328 RemoveApp(app_id);
221 } 329 }
222 330
223 } // namespace chromeos 331 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698