1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/chromeos/profiles/profile_helper.h"
6#include "chrome/browser/extensions/extension_assets_manager_chromeos.h"
7#include "chrome/browser/extensions/extension_garbage_collector_chromeos.h"
8#include "chrome/browser/extensions/extension_service.h"
9#include "components/user_manager/user_manager.h"
10#include "extensions/browser/extension_system.h"
11
12namespace extensions {
13
14bool ExtensionGarbageCollectorChromeOS::shared_extensions_garbage_collected_ =
15    false;
16
17ExtensionGarbageCollectorChromeOS::ExtensionGarbageCollectorChromeOS(
18    content::BrowserContext* context)
19    : ExtensionGarbageCollector(context),
20      disable_garbage_collection_(false) {
21}
22
23ExtensionGarbageCollectorChromeOS::~ExtensionGarbageCollectorChromeOS() {}
24
25// static
26ExtensionGarbageCollectorChromeOS* ExtensionGarbageCollectorChromeOS::Get(
27    content::BrowserContext* context) {
28  return static_cast<ExtensionGarbageCollectorChromeOS*>(
29      ExtensionGarbageCollector::Get(context));
30}
31
32// static
33void ExtensionGarbageCollectorChromeOS::ClearGarbageCollectedForTesting() {
34  shared_extensions_garbage_collected_ = false;
35}
36
37void ExtensionGarbageCollectorChromeOS::GarbageCollectExtensions() {
38  if (disable_garbage_collection_)
39    return;
40
41  // Process per-profile extensions dir.
42  ExtensionGarbageCollector::GarbageCollectExtensions();
43
44  if (!shared_extensions_garbage_collected_ &&
45      CanGarbageCollectSharedExtensions()) {
46    GarbageCollectSharedExtensions();
47    shared_extensions_garbage_collected_ = true;
48  }
49}
50
51bool ExtensionGarbageCollectorChromeOS::CanGarbageCollectSharedExtensions() {
52  user_manager::UserManager* user_manager = user_manager::UserManager::Get();
53  if (!user_manager) {
54    NOTREACHED();
55    return false;
56  }
57
58  const user_manager::UserList& active_users = user_manager->GetLoggedInUsers();
59  for (size_t i = 0; i < active_users.size(); i++) {
60    Profile* profile =
61        chromeos::ProfileHelper::Get()->GetProfileByUserUnsafe(active_users[i]);
62    ExtensionGarbageCollectorChromeOS* gc =
63        ExtensionGarbageCollectorChromeOS::Get(profile);
64    if (gc && gc->crx_installs_in_progress_ > 0)
65      return false;
66  }
67
68  return true;
69}
70
71void ExtensionGarbageCollectorChromeOS::GarbageCollectSharedExtensions() {
72  std::multimap<std::string, base::FilePath> paths;
73  if (ExtensionAssetsManagerChromeOS::CleanUpSharedExtensions(&paths)) {
74    ExtensionService* service =
75        ExtensionSystem::Get(context_)->extension_service();
76    if (!service->GetFileTaskRunner()->PostTask(
77            FROM_HERE,
78            base::Bind(&GarbageCollectExtensionsOnFileThread,
79                       ExtensionAssetsManagerChromeOS::GetSharedInstallDir(),
80                       paths))) {
81      NOTREACHED();
82    }
83  }
84}
85
86}  // namespace extensions
87