1// Copyright (c) 2013 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#ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_INSTALL_LIMITER_H_
6#define CHROME_BROWSER_CHROMEOS_EXTENSIONS_INSTALL_LIMITER_H_
7
8#include <queue>
9#include <set>
10
11#include "base/basictypes.h"
12#include "base/compiler_specific.h"
13#include "base/files/file_path.h"
14#include "base/memory/ref_counted.h"
15#include "base/memory/weak_ptr.h"
16#include "base/timer/timer.h"
17#include "chrome/browser/extensions/crx_installer.h"
18#include "components/keyed_service/core/keyed_service.h"
19#include "content/public/browser/notification_observer.h"
20#include "content/public/browser/notification_registrar.h"
21
22namespace extensions {
23
24// InstallLimiter defers big app installs after all small app installs and then
25// runs big app installs one by one. This improves first-time login experience.
26// See http://crbug.com/166296
27class InstallLimiter : public KeyedService,
28                       public content::NotificationObserver,
29                       public base::SupportsWeakPtr<InstallLimiter> {
30 public:
31  static InstallLimiter* Get(Profile* profile);
32
33  InstallLimiter();
34  virtual ~InstallLimiter();
35
36  void DisableForTest();
37
38  void Add(const scoped_refptr<CrxInstaller>& installer,
39           const base::FilePath& path);
40
41 private:
42  // DeferredInstall holds info to run a CrxInstaller later.
43  struct DeferredInstall {
44    DeferredInstall(const scoped_refptr<CrxInstaller>& installer,
45                   const base::FilePath& path);
46    ~DeferredInstall();
47
48    const scoped_refptr<CrxInstaller> installer;
49    const base::FilePath path;
50  };
51
52  typedef std::queue<DeferredInstall> DeferredInstallList;
53  typedef std::set<scoped_refptr<CrxInstaller> > CrxInstallerSet;
54
55  // Adds install info with size. If |size| is greater than a certain threshold,
56  // it stores the install info into |deferred_installs_| to run it later.
57  // Otherwise, it just runs the installer.
58  void AddWithSize(const scoped_refptr<CrxInstaller>& installer,
59                   const base::FilePath& path,
60                   int64 size);
61
62  // Checks and runs deferred big app installs when appropriate.
63  void CheckAndRunDeferrredInstalls();
64
65  // Starts install using passed-in info and observes |installer|'s done
66  // notification.
67  void RunInstall(const scoped_refptr<CrxInstaller>& installer,
68                  const base::FilePath& path);
69
70  // content::NotificationObserver overrides:
71  virtual void Observe(int type,
72                       const content::NotificationSource& source,
73                       const content::NotificationDetails& details) OVERRIDE;
74
75  content::NotificationRegistrar registrar_;
76
77  DeferredInstallList deferred_installs_;
78  CrxInstallerSet running_installers_;
79
80  // A timer to wait before running deferred big app install.
81  base::OneShotTimer<InstallLimiter> wait_timer_;
82
83  bool disabled_for_test_;
84
85  DISALLOW_COPY_AND_ASSIGN(InstallLimiter);
86};
87
88}  // namespace extensions
89
90#endif  // CHROME_BROWSER_CHROMEOS_EXTENSIONS_INSTALL_LIMITER_H_
91