Fix the duplicatedly commited composition text when switching IME.
[chromium-blink-merge.git] / chrome / browser / chromeos / extensions / install_limiter.cc
blob7bc865d520129f0cbf2b14ffd326154c3e71a1f3
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.
5 #include "chrome/browser/chromeos/extensions/install_limiter.h"
7 #include <string>
9 #include "base/bind.h"
10 #include "base/files/file_util.h"
11 #include "base/threading/sequenced_worker_pool.h"
12 #include "chrome/browser/chromeos/extensions/install_limiter_factory.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "content/public/browser/notification_details.h"
15 #include "content/public/browser/notification_source.h"
16 #include "extensions/browser/notification_types.h"
18 using content::BrowserThread;
20 namespace {
22 int64 GetFileSizeOnBlockingPool(const base::FilePath& file) {
23 DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
25 // Get file size. In case of error, sets 0 as file size to let the installer
26 // run and fail.
27 int64 size;
28 return base::GetFileSize(file, &size) ? size : 0;
31 } // namespace
33 namespace extensions {
35 ////////////////////////////////////////////////////////////////////////////////
36 // InstallLimiter::DeferredInstall
38 InstallLimiter::DeferredInstall::DeferredInstall(
39 const scoped_refptr<CrxInstaller>& installer,
40 const base::FilePath& path)
41 : installer(installer),
42 path(path) {
45 InstallLimiter::DeferredInstall::~DeferredInstall() {
48 ////////////////////////////////////////////////////////////////////////////////
49 // InstallLimiter
51 InstallLimiter* InstallLimiter::Get(Profile* profile) {
52 return InstallLimiterFactory::GetForProfile(profile);
55 InstallLimiter::InstallLimiter() : disabled_for_test_(false) {
58 InstallLimiter::~InstallLimiter() {
61 void InstallLimiter::DisableForTest() {
62 disabled_for_test_ = true;
65 void InstallLimiter::Add(const scoped_refptr<CrxInstaller>& installer,
66 const base::FilePath& path) {
67 // No deferred installs when disabled for test.
68 if (disabled_for_test_) {
69 installer->InstallCrx(path);
70 return;
73 base::PostTaskAndReplyWithResult(
74 BrowserThread::GetBlockingPool(),
75 FROM_HERE,
76 base::Bind(&GetFileSizeOnBlockingPool, path),
77 base::Bind(&InstallLimiter::AddWithSize, AsWeakPtr(), installer, path));
80 void InstallLimiter::AddWithSize(
81 const scoped_refptr<CrxInstaller>& installer,
82 const base::FilePath& path,
83 int64 size) {
84 const int64 kBigAppSizeThreshold = 1048576; // 1MB
86 if (size <= kBigAppSizeThreshold) {
87 RunInstall(installer, path);
89 // Stop wait timer and let install notification drive deferred installs.
90 wait_timer_.Stop();
91 return;
94 deferred_installs_.push(DeferredInstall(installer, path));
96 // When there are no running installs, wait a bit before running deferred
97 // installs to allow small app install to take precedence, especially when a
98 // big app is the first one in the list.
99 if (running_installers_.empty() && !wait_timer_.IsRunning()) {
100 const int kMaxWaitTimeInMs = 5000; // 5 seconds.
101 wait_timer_.Start(
102 FROM_HERE,
103 base::TimeDelta::FromMilliseconds(kMaxWaitTimeInMs),
104 this, &InstallLimiter::CheckAndRunDeferrredInstalls);
108 void InstallLimiter::CheckAndRunDeferrredInstalls() {
109 if (deferred_installs_.empty() || !running_installers_.empty())
110 return;
112 const DeferredInstall& deferred = deferred_installs_.front();
113 RunInstall(deferred.installer, deferred.path);
114 deferred_installs_.pop();
117 void InstallLimiter::RunInstall(const scoped_refptr<CrxInstaller>& installer,
118 const base::FilePath& path) {
119 registrar_.Add(this,
120 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
121 content::Source<CrxInstaller>(installer.get()));
123 installer->InstallCrx(path);
124 running_installers_.insert(installer);
127 void InstallLimiter::Observe(int type,
128 const content::NotificationSource& source,
129 const content::NotificationDetails& details) {
130 DCHECK_EQ(extensions::NOTIFICATION_CRX_INSTALLER_DONE, type);
132 registrar_.Remove(this, extensions::NOTIFICATION_CRX_INSTALLER_DONE, source);
134 const scoped_refptr<CrxInstaller> installer =
135 content::Source<extensions::CrxInstaller>(source).ptr();
136 running_installers_.erase(installer);
137 CheckAndRunDeferrredInstalls();
140 } // namespace extensions