OLD | NEW |
---|---|
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" |
10 #include "base/path_service.h" | 11 #include "base/path_service.h" |
11 #include "base/prefs/pref_registry_simple.h" | 12 #include "base/prefs/pref_registry_simple.h" |
12 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
13 #include "base/values.h" | 14 #include "base/values.h" |
14 #include "chrome/browser/chromeos/app_mode/kiosk_app_data.h" | 15 #include "chrome/browser/chromeos/app_mode/kiosk_app_data.h" |
15 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager_observer.h" | 16 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager_observer.h" |
17 #include "chrome/browser/chromeos/login/user_manager.h" | |
16 #include "chrome/browser/chromeos/settings/cros_settings.h" | 18 #include "chrome/browser/chromeos/settings/cros_settings.h" |
17 #include "chrome/common/chrome_notification_types.h" | 19 #include "chrome/common/chrome_notification_types.h" |
18 #include "chrome/common/chrome_paths.h" | 20 #include "chrome/common/chrome_paths.h" |
19 #include "chromeos/cryptohome/async_method_caller.h" | 21 #include "chromeos/cryptohome/async_method_caller.h" |
20 #include "content/public/browser/notification_details.h" | |
21 | 22 |
22 namespace chromeos { | 23 namespace chromeos { |
23 | 24 |
24 namespace { | 25 namespace { |
25 | 26 |
26 void OnRemoveAppCryptohomeComplete(const std::string& app, | 27 void OnRemoveAppCryptohomeComplete(const std::string& app, |
27 bool success, | 28 bool success, |
28 cryptohome::MountError return_code) { | 29 cryptohome::MountError return_code) { |
29 if (!success) { | 30 if (!success) { |
30 LOG(ERROR) << "Remove cryptohome for " << app | 31 LOG(ERROR) << "Remove cryptohome for " << app |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
63 name(data.name()), | 64 name(data.name()), |
64 icon(data.icon()), | 65 icon(data.icon()), |
65 is_loading(data.IsLoading()) { | 66 is_loading(data.IsLoading()) { |
66 } | 67 } |
67 | 68 |
68 KioskAppManager::App::App() : is_loading(false) {} | 69 KioskAppManager::App::App() : is_loading(false) {} |
69 KioskAppManager::App::~App() {} | 70 KioskAppManager::App::~App() {} |
70 | 71 |
71 std::string KioskAppManager::GetAutoLaunchApp() const { | 72 std::string KioskAppManager::GetAutoLaunchApp() const { |
72 std::string app_id; | 73 std::string app_id; |
73 if (CrosSettings::Get()->GetString(kKioskAutoLaunch, &app_id)) | 74 std::string auto_login_id; |
75 if (CrosSettings::Get()->GetString(kAccountsPrefDeviceLocalAccountAutoLoginId, | |
76 &auto_login_id) && | |
77 UserManager::ParseKioskAppUserId(auto_login_id, &app_id)) { | |
74 return app_id; | 78 return app_id; |
79 } | |
75 | 80 |
76 return std::string(); | 81 return std::string(); |
77 } | 82 } |
78 | 83 |
79 void KioskAppManager::SetAutoLaunchApp(const std::string& app_id) { | 84 void KioskAppManager::SetAutoLaunchApp(const std::string& app_id) { |
80 CrosSettings::Get()->SetString(kKioskAutoLaunch, app_id); | 85 CrosSettings::Get()->SetString(kAccountsPrefDeviceLocalAccountAutoLoginId, |
86 UserManager::FormatKioskAppUserId(app_id)); | |
87 CrosSettings::Get()->SetInteger(kAccountsPrefDeviceLocalAccountAutoLoginDelay, | |
88 0); | |
81 } | 89 } |
82 | 90 |
83 void KioskAppManager::AddApp(const std::string& app_id) { | 91 void KioskAppManager::AddApp(const std::string& app_id) { |
84 base::StringValue value(app_id); | 92 CrosSettings* cros_settings = CrosSettings::Get(); |
85 CrosSettings::Get()->AppendToList(kKioskApps, &value); | 93 const base::DictionaryValue* accounts_dict = NULL; |
94 cros_settings->GetDictionary(kAccountsPrefDeviceLocalAccounts, | |
95 &accounts_dict); | |
96 scoped_ptr<base::DictionaryValue> new_accounts_dict( | |
bartfab (slow)
2013/04/25 11:17:28
Nit: #include "base/memory/scoped_ptr.h"
Mattias Nissler (ping if slow)
2013/04/26 09:10:05
Done.
| |
97 accounts_dict ? accounts_dict->DeepCopy() : new base::DictionaryValue()); | |
98 | |
99 scoped_ptr<base::DictionaryValue> entry_dict(new base::DictionaryValue()); | |
bartfab (slow)
2013/04/25 11:17:28
What is the advantage of a scoped_ptr here if you
Mattias Nissler (ping if slow)
2013/04/26 09:10:05
I made that a habit, don't have to worry about mem
| |
100 entry_dict->SetStringWithoutPathExpansion( | |
101 kAccountsPrefDeviceLocalAccountsKeyKioskAppId, app_id); | |
102 new_accounts_dict->SetWithoutPathExpansion( | |
103 UserManager::FormatKioskAppUserId(app_id), entry_dict.release()); | |
104 cros_settings->Set(kAccountsPrefDeviceLocalAccounts, *new_accounts_dict); | |
86 } | 105 } |
87 | 106 |
88 void KioskAppManager::RemoveApp(const std::string& app_id) { | 107 void KioskAppManager::RemoveApp(const std::string& app_id) { |
89 base::StringValue value(app_id); | 108 CrosSettings* cros_settings = CrosSettings::Get(); |
90 CrosSettings::Get()->RemoveFromList(kKioskApps, &value); | 109 const base::DictionaryValue* accounts_dict = NULL; |
110 cros_settings->GetDictionary(kAccountsPrefDeviceLocalAccounts, | |
111 &accounts_dict); | |
112 | |
113 scoped_ptr<base::DictionaryValue> new_accounts_dict( | |
114 accounts_dict ? accounts_dict->DeepCopy() : new base::DictionaryValue()); | |
115 if (new_accounts_dict->RemoveWithoutPathExpansion( | |
116 UserManager::FormatKioskAppUserId(app_id), NULL)) { | |
117 cros_settings->Set(kAccountsPrefDeviceLocalAccounts, *new_accounts_dict); | |
118 } | |
91 } | 119 } |
92 | 120 |
93 void KioskAppManager::GetApps(Apps* apps) const { | 121 void KioskAppManager::GetApps(Apps* apps) const { |
94 apps->reserve(apps_.size()); | 122 apps->reserve(apps_.size()); |
95 for (size_t i = 0; i < apps_.size(); ++i) | 123 for (size_t i = 0; i < apps_.size(); ++i) |
96 apps->push_back(App(*apps_[i])); | 124 apps->push_back(App(*apps_[i])); |
97 } | 125 } |
98 | 126 |
99 bool KioskAppManager::GetApp(const std::string& app_id, App* app) const { | 127 bool KioskAppManager::GetApp(const std::string& app_id, App* app) const { |
100 const KioskAppData* data = GetAppData(app_id); | 128 const KioskAppData* data = GetAppData(app_id); |
101 if (!data) | 129 if (!data) |
102 return false; | 130 return false; |
103 | 131 |
104 *app = App(*data); | 132 *app = App(*data); |
105 return true; | 133 return true; |
106 } | 134 } |
107 | 135 |
108 const base::RefCountedString* KioskAppManager::GetAppRawIcon( | 136 const base::RefCountedString* KioskAppManager::GetAppRawIcon( |
109 const std::string& app_id) const { | 137 const std::string& app_id) const { |
110 const KioskAppData* data = GetAppData(app_id); | 138 const KioskAppData* data = GetAppData(app_id); |
111 if (!data) | 139 if (!data) |
112 return NULL; | 140 return NULL; |
113 | 141 |
114 return data->raw_icon(); | 142 return data->raw_icon(); |
115 } | 143 } |
116 | 144 |
117 bool KioskAppManager::GetDisableBailoutShortcut() const { | 145 bool KioskAppManager::GetDisableBailoutShortcut() const { |
118 bool disable; | 146 bool enable; |
119 if (CrosSettings::Get()->GetBoolean(kKioskDisableBailoutShortcut, &disable)) | 147 if (CrosSettings::Get()->GetBoolean( |
120 return disable; | 148 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled, &enable)) { |
149 return !enable; | |
150 } | |
121 | 151 |
122 return false; | 152 return false; |
123 } | 153 } |
124 | 154 |
125 void KioskAppManager::AddObserver(KioskAppManagerObserver* observer) { | 155 void KioskAppManager::AddObserver(KioskAppManagerObserver* observer) { |
126 observers_.AddObserver(observer); | 156 observers_.AddObserver(observer); |
127 } | 157 } |
128 | 158 |
129 void KioskAppManager::RemoveObserver(KioskAppManagerObserver* observer) { | 159 void KioskAppManager::RemoveObserver(KioskAppManagerObserver* observer) { |
130 observers_.RemoveObserver(observer); | 160 observers_.RemoveObserver(observer); |
131 } | 161 } |
132 | 162 |
133 KioskAppManager::KioskAppManager() { | 163 KioskAppManager::KioskAppManager() { |
134 UpdateAppData(); | 164 UpdateAppData(); |
135 CrosSettings::Get()->AddSettingsObserver(kKioskApps, this); | 165 CrosSettings::Get()->AddSettingsObserver( |
166 kAccountsPrefDeviceLocalAccounts, this); | |
136 } | 167 } |
137 | 168 |
138 KioskAppManager::~KioskAppManager() {} | 169 KioskAppManager::~KioskAppManager() {} |
139 | 170 |
140 void KioskAppManager::CleanUp() { | 171 void KioskAppManager::CleanUp() { |
141 CrosSettings::Get()->RemoveSettingsObserver(kKioskApps, this); | 172 CrosSettings::Get()->RemoveSettingsObserver( |
173 kAccountsPrefDeviceLocalAccounts, this); | |
142 apps_.clear(); | 174 apps_.clear(); |
143 } | 175 } |
144 | 176 |
145 const KioskAppData* KioskAppManager::GetAppData( | 177 const KioskAppData* KioskAppManager::GetAppData( |
146 const std::string& app_id) const { | 178 const std::string& app_id) const { |
147 for (size_t i = 0; i < apps_.size(); ++i) { | 179 for (size_t i = 0; i < apps_.size(); ++i) { |
148 const KioskAppData* data = apps_[i]; | 180 const KioskAppData* data = apps_[i]; |
149 if (data->id() == app_id) | 181 if (data->id() == app_id) |
150 return data; | 182 return data; |
151 } | 183 } |
152 | 184 |
153 return NULL; | 185 return NULL; |
154 } | 186 } |
155 | 187 |
156 void KioskAppManager::UpdateAppData() { | 188 void KioskAppManager::UpdateAppData() { |
157 // Gets app id to data mapping for existing apps. | 189 // Gets app id to data mapping for existing apps. |
158 std::map<std::string, KioskAppData*> old_apps; | 190 std::map<std::string, KioskAppData*> old_apps; |
159 for (size_t i = 0; i < apps_.size(); ++i) | 191 for (size_t i = 0; i < apps_.size(); ++i) |
160 old_apps[apps_[i]->id()] = apps_[i]; | 192 old_apps[apps_[i]->id()] = apps_[i]; |
161 apps_.weak_clear(); // |old_apps| takes ownership | 193 apps_.weak_clear(); // |old_apps| takes ownership |
162 | 194 |
163 const base::ListValue* new_apps; | 195 const base::DictionaryValue* local_accounts; |
164 CHECK(CrosSettings::Get()->GetList(kKioskApps, &new_apps)); | 196 if (CrosSettings::Get()->GetDictionary(kAccountsPrefDeviceLocalAccounts, |
197 &local_accounts)) { | |
198 // Re-populates |apps_| and reuses existing KioskAppData when possible. | |
199 for (base::DictionaryValue::Iterator account(*local_accounts); | |
200 !account.IsAtEnd(); account.Advance()) { | |
201 const base::DictionaryValue* entry_dict = NULL; | |
202 if (!account.value().GetAsDictionary(&entry_dict)) { | |
203 NOTREACHED(); | |
bartfab (slow)
2013/04/25 11:17:28
Nit: #include "base/logging.h"
Mattias Nissler (ping if slow)
2013/04/26 09:10:05
Done.
| |
204 continue; | |
205 } | |
165 | 206 |
166 // Re-populates |apps_| and reuses existing KioskAppData when possible. | 207 std::string kiosk_app_id; |
167 for (base::ListValue::const_iterator new_it = new_apps->begin(); | 208 if (!entry_dict->GetStringWithoutPathExpansion( |
bartfab (slow)
2013/04/25 11:17:28
The code should look at account->key() instead to
Mattias Nissler (ping if slow)
2013/04/26 09:10:05
Switched to the type enum.
| |
168 new_it != new_apps->end(); | 209 kAccountsPrefDeviceLocalAccountsKeyKioskAppId, |
169 ++new_it) { | 210 &kiosk_app_id)) { |
170 std::string id; | 211 // Not a kiosk app. |
171 CHECK((*new_it)->GetAsString(&id)); | 212 continue; |
213 } | |
172 | 214 |
173 std::map<std::string, KioskAppData*>::iterator old_it = old_apps.find(id); | 215 // TODO(mnissler): Support non-CWS update URLs. |
174 if (old_it != old_apps.end()) { | 216 |
175 apps_.push_back(old_it->second); | 217 std::map<std::string, KioskAppData*>::iterator old_it = |
176 old_apps.erase(old_it); | 218 old_apps.find(kiosk_app_id); |
177 } else { | 219 if (old_it != old_apps.end()) { |
178 KioskAppData* new_app = new KioskAppData(this, id); | 220 apps_.push_back(old_it->second); |
179 apps_.push_back(new_app); // Takes ownership of |new_app|. | 221 old_apps.erase(old_it); |
180 new_app->Load(); | 222 } else { |
223 KioskAppData* new_app = new KioskAppData(this, kiosk_app_id); | |
224 apps_.push_back(new_app); // Takes ownership of |new_app|. | |
225 new_app->Load(); | |
226 } | |
181 } | 227 } |
182 } | 228 } |
183 | 229 |
184 // Clears cache and deletes the remaining old data. | 230 // Clears cache and deletes the remaining old data. |
185 for (std::map<std::string, KioskAppData*>::iterator it = old_apps.begin(); | 231 for (std::map<std::string, KioskAppData*>::iterator it = old_apps.begin(); |
186 it != old_apps.end(); ++it) { | 232 it != old_apps.end(); ++it) { |
187 it->second->ClearCache(); | 233 it->second->ClearCache(); |
188 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( | 234 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( |
189 it->first, base::Bind(&OnRemoveAppCryptohomeComplete, it->first)); | 235 it->first, base::Bind(&OnRemoveAppCryptohomeComplete, it->first)); |
190 } | 236 } |
191 STLDeleteValues(&old_apps); | 237 STLDeleteValues(&old_apps); |
238 | |
239 FOR_EACH_OBSERVER(KioskAppManagerObserver, observers_, | |
240 OnKioskAppsListChanged()); | |
192 } | 241 } |
193 | 242 |
194 void KioskAppManager::Observe(int type, | 243 void KioskAppManager::Observe(int type, |
195 const content::NotificationSource& source, | 244 const content::NotificationSource& source, |
196 const content::NotificationDetails& details) { | 245 const content::NotificationDetails& details) { |
197 DCHECK_EQ(chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED, type); | 246 DCHECK_EQ(chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED, type); |
198 DCHECK_EQ(kKioskApps, | |
199 *content::Details<const std::string>(details).ptr()); | |
200 | |
201 UpdateAppData(); | 247 UpdateAppData(); |
202 } | 248 } |
203 | 249 |
204 void KioskAppManager::GetKioskAppIconCacheDir(base::FilePath* cache_dir) { | 250 void KioskAppManager::GetKioskAppIconCacheDir(base::FilePath* cache_dir) { |
205 base::FilePath user_data_dir; | 251 base::FilePath user_data_dir; |
206 CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)); | 252 CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)); |
207 *cache_dir = user_data_dir.AppendASCII(kIconCacheDir); | 253 *cache_dir = user_data_dir.AppendASCII(kIconCacheDir); |
208 } | 254 } |
209 | 255 |
210 void KioskAppManager::OnKioskAppDataChanged(const std::string& app_id) { | 256 void KioskAppManager::OnKioskAppDataChanged(const std::string& app_id) { |
211 FOR_EACH_OBSERVER(KioskAppManagerObserver, | 257 FOR_EACH_OBSERVER(KioskAppManagerObserver, |
212 observers_, | 258 observers_, |
213 OnKioskAppDataChanged(app_id)); | 259 OnKioskAppDataChanged(app_id)); |
214 } | 260 } |
215 | 261 |
216 void KioskAppManager::OnKioskAppDataLoadFailure(const std::string& app_id) { | 262 void KioskAppManager::OnKioskAppDataLoadFailure(const std::string& app_id) { |
217 FOR_EACH_OBSERVER(KioskAppManagerObserver, | 263 FOR_EACH_OBSERVER(KioskAppManagerObserver, |
218 observers_, | 264 observers_, |
219 OnKioskAppDataLoadFailure(app_id)); | 265 OnKioskAppDataLoadFailure(app_id)); |
220 RemoveApp(app_id); | 266 RemoveApp(app_id); |
221 } | 267 } |
222 | 268 |
223 } // namespace chromeos | 269 } // namespace chromeos |
OLD | NEW |