OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/arc/arc_kiosk_app_manager.h> | 5 #include <chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_manager.h> |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/barrier_closure.h" | 10 #include "base/barrier_closure.h" |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/bind_helpers.h" | 12 #include "base/bind_helpers.h" |
13 #include "base/callback.h" | 13 #include "base/callback.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/memory/ptr_util.h" | |
15 #include "base/values.h" | 16 #include "base/values.h" |
16 #include "chrome/browser/browser_process.h" | 17 #include "chrome/browser/browser_process.h" |
17 #include "chrome/browser/lifetime/application_lifetime.h" | 18 #include "chrome/browser/lifetime/application_lifetime.h" |
18 #include "chromeos/cryptohome/async_method_caller.h" | 19 #include "chromeos/cryptohome/async_method_caller.h" |
19 #include "chromeos/cryptohome/cryptohome_parameters.h" | 20 #include "chromeos/cryptohome/cryptohome_parameters.h" |
20 #include "chromeos/dbus/cryptohome_client.h" | 21 #include "chromeos/dbus/cryptohome_client.h" |
21 #include "chromeos/dbus/dbus_thread_manager.h" | 22 #include "chromeos/dbus/dbus_thread_manager.h" |
22 #include "chromeos/settings/cros_settings_names.h" | 23 #include "chromeos/settings/cros_settings_names.h" |
23 #include "components/arc/arc_util.h" | 24 #include "components/arc/arc_util.h" |
24 #include "components/prefs/pref_registry_simple.h" | 25 #include "components/prefs/pref_registry_simple.h" |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
89 base::Closure())); | 90 base::Closure())); |
90 } | 91 } |
91 } | 92 } |
92 | 93 |
93 // This class is owned by ChromeBrowserMainPartsChromeos. | 94 // This class is owned by ChromeBrowserMainPartsChromeos. |
94 static ArcKioskAppManager* g_arc_kiosk_app_manager = nullptr; | 95 static ArcKioskAppManager* g_arc_kiosk_app_manager = nullptr; |
95 | 96 |
96 } // namespace | 97 } // namespace |
97 | 98 |
98 // static | 99 // static |
100 const char ArcKioskAppManager::kArcKioskDictionaryName[] = "arc-kiosk"; | |
101 | |
102 // static | |
99 void ArcKioskAppManager::RegisterPrefs(PrefRegistrySimple* registry) { | 103 void ArcKioskAppManager::RegisterPrefs(PrefRegistrySimple* registry) { |
104 registry->RegisterDictionaryPref(kArcKioskDictionaryName); | |
100 registry->RegisterListPref(kArcKioskUsersToRemove); | 105 registry->RegisterListPref(kArcKioskUsersToRemove); |
101 } | 106 } |
102 | 107 |
103 // static | 108 // static |
104 void ArcKioskAppManager::RemoveObsoleteCryptohomes() { | 109 void ArcKioskAppManager::RemoveObsoleteCryptohomes() { |
105 chromeos::CryptohomeClient* const client = | 110 chromeos::CryptohomeClient* const client = |
106 chromeos::DBusThreadManager::Get()->GetCryptohomeClient(); | 111 chromeos::DBusThreadManager::Get()->GetCryptohomeClient(); |
107 client->WaitForServiceToBeAvailable( | 112 client->WaitForServiceToBeAvailable( |
108 base::Bind(&PerformDelayedCryptohomeRemovals)); | 113 base::Bind(&PerformDelayedCryptohomeRemovals)); |
109 } | 114 } |
110 | 115 |
111 ArcKioskAppManager::ArcKioskApp::ArcKioskApp(const ArcKioskApp& other) = | |
112 default; | |
113 | |
114 ArcKioskAppManager::ArcKioskApp::ArcKioskApp( | |
115 const policy::ArcKioskAppBasicInfo& app_info, | |
116 const AccountId& account_id, | |
117 const std::string& name) | |
118 : app_info_(app_info), account_id_(account_id), name_(name) {} | |
119 | |
120 ArcKioskAppManager::ArcKioskApp::~ArcKioskApp() = default; | |
121 | |
122 bool ArcKioskAppManager::ArcKioskApp::operator==( | |
123 const policy::ArcKioskAppBasicInfo& app_info) const { | |
124 return this->app_info_ == app_info; | |
125 } | |
126 | |
127 // static | 116 // static |
128 ArcKioskAppManager* ArcKioskAppManager::Get() { | 117 ArcKioskAppManager* ArcKioskAppManager::Get() { |
129 return g_arc_kiosk_app_manager; | 118 return g_arc_kiosk_app_manager; |
130 } | 119 } |
131 | 120 |
132 ArcKioskAppManager::ArcKioskAppManager() | 121 ArcKioskAppManager::ArcKioskAppManager() |
133 : auto_launch_account_id_(EmptyAccountId()) { | 122 : auto_launch_account_id_(EmptyAccountId()) { |
134 DCHECK(!g_arc_kiosk_app_manager); // Only one instance is allowed. | 123 DCHECK(!g_arc_kiosk_app_manager); // Only one instance is allowed. |
135 UpdateApps(); | 124 UpdateApps(); |
136 local_accounts_subscription_ = CrosSettings::Get()->AddSettingsObserver( | 125 local_accounts_subscription_ = CrosSettings::Get()->AddSettingsObserver( |
(...skipping 10 matching lines...) Expand all Loading... | |
147 local_accounts_subscription_.reset(); | 136 local_accounts_subscription_.reset(); |
148 local_account_auto_login_id_subscription_.reset(); | 137 local_account_auto_login_id_subscription_.reset(); |
149 apps_.clear(); | 138 apps_.clear(); |
150 g_arc_kiosk_app_manager = nullptr; | 139 g_arc_kiosk_app_manager = nullptr; |
151 } | 140 } |
152 | 141 |
153 const AccountId& ArcKioskAppManager::GetAutoLaunchAccountId() const { | 142 const AccountId& ArcKioskAppManager::GetAutoLaunchAccountId() const { |
154 return auto_launch_account_id_; | 143 return auto_launch_account_id_; |
155 } | 144 } |
156 | 145 |
157 const ArcKioskAppManager::ArcKioskApp* ArcKioskAppManager::GetAppByAccountId( | 146 const ArcKioskAppData* ArcKioskAppManager::GetAppByAccountId( |
158 const AccountId& account_id) { | 147 const AccountId& account_id) { |
159 for (auto& app : GetAllApps()) | 148 for (auto& app : apps_) |
Luis Héctor Chávez
2017/04/06 16:16:50
Ugh missed this in a previous review. nit: Add bra
Sergey Poromov
2017/04/07 02:09:37
Done.
| |
160 if (app.account_id() == account_id) | 149 if (app->account_id() == account_id) |
161 return &app; | 150 return app.get(); |
162 return nullptr; | 151 return nullptr; |
163 } | 152 } |
164 | 153 |
154 void ArcKioskAppManager::GetAllApps(Apps* apps) const { | |
155 apps->clear(); | |
156 apps->reserve(apps_.size()); | |
157 for (auto& app : apps_) | |
158 apps->push_back(app.get()); | |
159 } | |
160 | |
161 void ArcKioskAppManager::UpdateNameAndIcon(const std::string& app_id, | |
162 const std::string& name, | |
163 const gfx::ImageSkia& icon) { | |
164 for (auto& app : apps_) { | |
165 if (app->app_id() == app_id) { | |
166 app->SetCache(name, icon); | |
167 return; | |
168 } | |
169 } | |
170 } | |
171 | |
165 void ArcKioskAppManager::AddObserver(ArcKioskAppManagerObserver* observer) { | 172 void ArcKioskAppManager::AddObserver(ArcKioskAppManagerObserver* observer) { |
166 observers_.AddObserver(observer); | 173 observers_.AddObserver(observer); |
167 } | 174 } |
168 | 175 |
169 void ArcKioskAppManager::RemoveObserver(ArcKioskAppManagerObserver* observer) { | 176 void ArcKioskAppManager::RemoveObserver(ArcKioskAppManagerObserver* observer) { |
170 observers_.RemoveObserver(observer); | 177 observers_.RemoveObserver(observer); |
171 } | 178 } |
172 | 179 |
173 void ArcKioskAppManager::UpdateApps() { | 180 void ArcKioskAppManager::UpdateApps() { |
174 // Do not populate ARC kiosk apps if ARC kiosk apps can't be run on the | 181 // Do not populate ARC kiosk apps if ARC kiosk apps can't be run on the |
175 // device. | 182 // device. |
176 // Apps won't be added to kiosk Apps menu and won't be auto-launched. | 183 // Apps won't be added to kiosk Apps menu and won't be auto-launched. |
177 if (!arc::IsArcKioskAvailable()) { | 184 if (!arc::IsArcKioskAvailable()) { |
178 VLOG(1) << "Device doesn't support ARC kiosk"; | 185 VLOG(1) << "Device doesn't support ARC kiosk"; |
179 return; | 186 return; |
180 } | 187 } |
181 | 188 |
182 // Store current apps. We will compare old and new apps to determine which | 189 // Store current apps. We will compare old and new apps to determine which |
183 // apps are new, and which were deleted. | 190 // apps are new, and which were deleted. |
184 ArcKioskApps old_apps(std::move(apps_)); | 191 std::map<std::string, std::unique_ptr<ArcKioskAppData>> old_apps; |
185 | 192 for (auto& app : apps_) |
193 old_apps[app->app_id()] = std::move(app); | |
194 apps_.clear(); | |
186 auto_launch_account_id_.clear(); | 195 auto_launch_account_id_.clear(); |
187 auto_launched_with_zero_delay_ = false; | 196 auto_launched_with_zero_delay_ = false; |
188 std::string auto_login_account_id_from_settings; | 197 std::string auto_login_account_id_from_settings; |
189 CrosSettings::Get()->GetString(kAccountsPrefDeviceLocalAccountAutoLoginId, | 198 CrosSettings::Get()->GetString(kAccountsPrefDeviceLocalAccountAutoLoginId, |
190 &auto_login_account_id_from_settings); | 199 &auto_login_account_id_from_settings); |
191 | 200 |
192 // Re-populates |apps_| and reuses existing apps when possible. | 201 // Re-populates |apps_| and reuses existing apps when possible. |
193 const std::vector<policy::DeviceLocalAccount> device_local_accounts = | 202 const std::vector<policy::DeviceLocalAccount> device_local_accounts = |
194 policy::GetDeviceLocalAccounts(CrosSettings::Get()); | 203 policy::GetDeviceLocalAccounts(CrosSettings::Get()); |
195 for (auto account : device_local_accounts) { | 204 for (auto account : device_local_accounts) { |
196 if (account.type != policy::DeviceLocalAccount::TYPE_ARC_KIOSK_APP) | 205 if (account.type != policy::DeviceLocalAccount::TYPE_ARC_KIOSK_APP) |
197 continue; | 206 continue; |
198 | 207 |
199 const AccountId account_id(AccountId::FromUserEmail(account.user_id)); | 208 const AccountId account_id(AccountId::FromUserEmail(account.user_id)); |
200 | 209 |
201 if (account.account_id == auto_login_account_id_from_settings) { | 210 if (account.account_id == auto_login_account_id_from_settings) { |
202 auto_launch_account_id_ = account_id; | 211 auto_launch_account_id_ = account_id; |
203 int auto_launch_delay = 0; | 212 int auto_launch_delay = 0; |
204 CrosSettings::Get()->GetInteger( | 213 CrosSettings::Get()->GetInteger( |
205 kAccountsPrefDeviceLocalAccountAutoLoginDelay, &auto_launch_delay); | 214 kAccountsPrefDeviceLocalAccountAutoLoginDelay, &auto_launch_delay); |
206 auto_launched_with_zero_delay_ = auto_launch_delay == 0; | 215 auto_launched_with_zero_delay_ = auto_launch_delay == 0; |
207 } | 216 } |
208 | 217 |
209 auto old_it = | 218 // Apps are keyed by package name. http://crbug.com/665904 |
210 std::find(old_apps.begin(), old_apps.end(), account.arc_kiosk_app_info); | 219 auto old_it = old_apps.find(account.arc_kiosk_app_info.package_name()); |
211 if (old_it != old_apps.end()) { | 220 if (old_it != old_apps.end()) { |
212 apps_.push_back(std::move(*old_it)); | 221 apps_.push_back(std::move(old_it->second)); |
213 old_apps.erase(old_it); | 222 old_apps.erase(old_it); |
214 } else { | 223 } else { |
215 // Use package name when display name is not specified. | 224 // Use package name when display name is not specified. |
216 std::string name = account.arc_kiosk_app_info.package_name(); | 225 std::string name = account.arc_kiosk_app_info.package_name(); |
217 if (!account.arc_kiosk_app_info.display_name().empty()) | 226 if (!account.arc_kiosk_app_info.display_name().empty()) |
218 name = account.arc_kiosk_app_info.display_name(); | 227 name = account.arc_kiosk_app_info.display_name(); |
219 apps_.push_back( | 228 apps_.push_back(base::MakeUnique<ArcKioskAppData>( |
220 ArcKioskApp(account.arc_kiosk_app_info, account_id, name)); | 229 account.arc_kiosk_app_info.package_name(), account_id, name)); |
230 apps_.back()->LoadFromCache(); | |
221 } | 231 } |
222 CancelDelayedCryptohomeRemoval(cryptohome::Identification(account_id)); | 232 CancelDelayedCryptohomeRemoval(cryptohome::Identification(account_id)); |
223 } | 233 } |
224 | 234 |
225 ClearRemovedApps(old_apps); | 235 ClearRemovedApps(old_apps); |
226 | 236 |
227 for (auto& observer : observers_) { | 237 for (auto& observer : observers_) { |
228 observer.OnArcKioskAppsChanged(); | 238 observer.OnArcKioskAppsChanged(); |
229 } | 239 } |
230 } | 240 } |
231 | 241 |
232 void ArcKioskAppManager::ClearRemovedApps( | 242 void ArcKioskAppManager::ClearRemovedApps( |
233 const std::vector<ArcKioskApp>& old_apps) { | 243 const std::map<std::string, std::unique_ptr<ArcKioskAppData>>& old_apps) { |
234 // Check if currently active user must be deleted. | 244 // Check if currently active user must be deleted. |
235 bool active_user_to_be_deleted = false; | 245 bool active_user_to_be_deleted = false; |
236 const user_manager::User* active_user = | 246 const user_manager::User* active_user = |
237 user_manager::UserManager::Get()->GetActiveUser(); | 247 user_manager::UserManager::Get()->GetActiveUser(); |
238 if (active_user) { | 248 if (active_user) { |
239 const AccountId active_account_id = active_user->GetAccountId(); | 249 const AccountId active_account_id = active_user->GetAccountId(); |
240 for (const auto& it : old_apps) { | 250 for (const auto& it : old_apps) { |
241 if (it.account_id() == active_account_id) { | 251 if (it.second->account_id() == active_account_id) { |
242 active_user_to_be_deleted = true; | 252 active_user_to_be_deleted = true; |
243 break; | 253 break; |
244 } | 254 } |
245 } | 255 } |
246 } | 256 } |
247 | 257 |
248 // Remove cryptohome | 258 // Remove cryptohome |
249 for (auto& entry : old_apps) { | 259 for (auto& entry : old_apps) { |
250 const cryptohome::Identification cryptohome_id(entry.account_id()); | 260 entry.second->ClearCache(); |
261 const cryptohome::Identification cryptohome_id(entry.second->account_id()); | |
251 if (active_user_to_be_deleted) { | 262 if (active_user_to_be_deleted) { |
252 // Schedule cryptohome removal after active user logout. | 263 // Schedule cryptohome removal after active user logout. |
253 ScheduleDelayedCryptohomeRemoval(cryptohome_id); | 264 ScheduleDelayedCryptohomeRemoval(cryptohome_id); |
254 } else { | 265 } else { |
255 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( | 266 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( |
256 cryptohome_id, base::Bind(&OnRemoveAppCryptohomeComplete, | 267 cryptohome_id, base::Bind(&OnRemoveAppCryptohomeComplete, |
257 cryptohome_id, base::Closure())); | 268 cryptohome_id, base::Closure())); |
258 } | 269 } |
259 } | 270 } |
260 | 271 |
261 if (active_user_to_be_deleted) | 272 if (active_user_to_be_deleted) |
262 chrome::AttemptUserExit(); | 273 chrome::AttemptUserExit(); |
263 } | 274 } |
264 | 275 |
265 } // namespace chromeos | 276 } // namespace chromeos |
OLD | NEW |