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