1// Copyright 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_EXTENSIONS_API_SYSTEM_INFO_SYSTEM_INFO_PROVIDER_H_
6#define CHROME_BROWSER_EXTENSIONS_API_SYSTEM_INFO_SYSTEM_INFO_PROVIDER_H_
7
8#include <queue>
9
10#include "base/bind.h"
11#include "base/callback.h"
12#include "base/memory/ref_counted.h"
13#include "base/threading/sequenced_worker_pool.h"
14#include "content/public/browser/browser_thread.h"
15
16namespace extensions {
17
18// An abstract base class for all kinds of system information providers. Each
19// kind of SystemInfoProvider is a single shared instance. It is created if
20// needed, and destroyed at exit time. This is done via LazyInstance and
21// scoped_refptr.
22//
23// The SystemInfoProvider is designed to query system information on the worker
24// pool. It also maintains a queue of callbacks on the UI thread which are
25// waiting for the completion of querying operation. Once the query operation
26// is completed, all pending callbacks in the queue get called on the UI
27// thread. In this way, it avoids frequent querying operation in case of lots
28// of query requests, e.g. calling systemInfo.cpu.get repeatedly in an
29// extension process.
30//
31// Each kind of SystemInfoProvider should satisfy an API query in a subclass on
32// the blocking pool.
33class SystemInfoProvider
34    : public base::RefCountedThreadSafe<SystemInfoProvider> {
35 public:
36  // Callback type for completing to get information. The argument indicates
37  // whether its contents are valid, for example, no error occurs in querying
38  // the information.
39  typedef base::Callback<void(bool)> QueryInfoCompletionCallback;
40  typedef std::queue<QueryInfoCompletionCallback> CallbackQueue;
41
42  SystemInfoProvider();
43
44  // Override to do any prepare work on UI thread before |QueryInfo()| gets
45  // called.
46  virtual void PrepareQueryOnUIThread();
47
48  // The parameter |do_query_info_callback| is query info task which is posted
49  // to SystemInfoProvider sequenced worker pool.
50  //
51  // You can do any initial things of *InfoProvider before start to query info.
52  // While overriding this method, |do_query_info_callback| *must* be called
53  // directly or indirectly.
54  //
55  // Sample usage please refer to StorageInfoProvider.
56  virtual void InitializeProvider(const base::Closure& do_query_info_callback);
57
58  // Start to query the system information. Should be called on UI thread.
59  // The |callback| will get called once the query is completed.
60  //
61  // If the parameter |callback| itself calls StartQueryInfo(callback2),
62  // callback2 will be called immediately rather than triggering another call to
63  // the system.
64  void StartQueryInfo(const QueryInfoCompletionCallback& callback);
65
66 protected:
67  virtual ~SystemInfoProvider();
68
69 private:
70  friend class base::RefCountedThreadSafe<SystemInfoProvider>;
71
72  // Interface to query the system information synchronously.
73  // Return true if no error occurs.
74  // Should be called in the blocking pool.
75  virtual bool QueryInfo() = 0;
76
77  // Called on UI thread. The |success| parameter means whether it succeeds
78  // to get the information.
79  void OnQueryCompleted(bool success);
80
81  void StartQueryInfoPostInitialization();
82
83  // The queue of callbacks waiting for the info querying completion. It is
84  // maintained on the UI thread.
85  CallbackQueue callbacks_;
86
87  // Indicates if it is waiting for the querying completion.
88  bool is_waiting_for_completion_;
89
90  // Sequenced worker pool to make the operation of querying information get
91  // executed in order.
92  scoped_refptr<base::SequencedTaskRunner> worker_pool_;
93
94  DISALLOW_COPY_AND_ASSIGN(SystemInfoProvider);
95};
96
97}  // namespace extensions
98
99#endif  // CHROME_BROWSER_EXTENSIONS_API_SYSTEM_INFO_SYSTEM_INFO_PROVIDER_H_
100