1 // Copyright 2018 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_COMPONENT_UPDATER_FAKE_CROS_COMPONENT_MANAGER_H_
6 #define CHROME_BROWSER_COMPONENT_UPDATER_FAKE_CROS_COMPONENT_MANAGER_H_
7 
8 #include <list>
9 #include <map>
10 #include <memory>
11 #include <set>
12 #include <string>
13 
14 #include "base/callback.h"
15 #include "base/files/file_path.h"
16 #include "base/macros.h"
17 #include "base/synchronization/lock.h"
18 #include "chrome/browser/component_updater/cros_component_manager.h"
19 
20 namespace component_updater {
21 
22 // This fake implementation of cros component manager. Intended to be used in
23 // tests to abstract away the cros component manager dependency on imageloader
24 // and component updater services, and local file system.
25 class FakeCrOSComponentManager : public CrOSComponentManager {
26  public:
27   // Information about how fake component manager should "load" a component.
28   struct ComponentInfo {
29     ComponentInfo(Error load_response,
30                   const base::FilePath& install_path,
31                   const base::FilePath& mount_path);
32     ~ComponentInfo();
33 
34     // The status load requests for the component should produce.
35     Error load_response;
36 
37     // The local path where the fake component manager thinks the component is
38     // installed.
39     base::FilePath install_path;
40 
41     // The path where the fake component manager thinks the component is
42     // mounted.
43     base::FilePath mount_path;
44   };
45 
46   FakeCrOSComponentManager();
47 
set_queue_load_requests(bool queue_load_requests)48   void set_queue_load_requests(bool queue_load_requests) {
49     queue_load_requests_ = queue_load_requests;
50   }
set_supported_components(const std::set<std::string> & components)51   void set_supported_components(const std::set<std::string>& components) {
52     supported_components_ = components;
53   }
set_unload_component_result(bool result)54   void set_unload_component_result(bool result) {
55     unload_component_result_ = result;
56   }
57   void SetRegisteredComponents(const std::set<std::string>& components);
58 
59   // Finishes a queued component load request. Should be used only if
60   // |queue_load_requests_| is set.
61   bool FinishLoadRequest(const std::string& name, const ComponentInfo& state);
62 
63   // If the component is "loaded", clears the recorded install and mount paths,
64   // and sets the info about how future load requests for the component should
65   // be handled.
66   bool ResetComponentState(const std::string& name, const ComponentInfo& state);
67 
68   // Whether any component loads are pending. Expected to be used only if
69   // |queue_load_requests_| is set.
70   bool HasPendingInstall(const std::string& name) const;
71 
72   // Whether the next pending component load requests triggers immediate
73   // component update request. Expected to be used only if
74   // |queue_load_requests_| is set.
75   bool UpdateRequested(const std::string& name) const;
76 
77   // CrOSComponentManager:
78   void SetDelegate(Delegate* delegate) override;
79   void Load(const std::string& name,
80             MountPolicy mount_policy,
81             UpdatePolicy update_policy,
82             LoadCallback load_callback) override;
83   bool Unload(const std::string& name) override;
84   void RegisterCompatiblePath(const std::string& name,
85                               const base::FilePath& path) override;
86   void UnregisterCompatiblePath(const std::string& name) override;
87   base::FilePath GetCompatiblePath(const std::string& name) const override;
88   bool IsRegisteredMayBlock(const std::string& name) override;
89   void RegisterInstalled() override;
90 
91  protected:
92   ~FakeCrOSComponentManager() override;
93 
94  private:
95   // Describes pending component load request.
96   struct LoadRequest {
97     LoadRequest(bool mount_requested, bool needs_update, LoadCallback callback);
98     ~LoadRequest();
99 
100     // Whether the component should be mounted as part of the load request.
101     bool mount_requested;
102 
103     // Whether the request should start immediate component update check.
104     bool needs_update;
105 
106     // The load request callback.
107     LoadCallback callback;
108   };
109 
110   // Handles a load request for a component, either by queueing it (if
111   // queue_load_requests_ is set), or setting the new component state depending
112   // on component_infos_.
113   // |name|: the component name.
114   // |mount_requested|: whether the component mount was requested as part of the
115   //     load request.
116   // |needs_update|: whether the load request triggers immediate update attempt.
117   // |callback|: to be called when the load request finishes.
118   void HandlePendingRequest(const std::string& name,
119                             bool mount_requested,
120                             bool needs_update,
121                             LoadCallback callback);
122   // Updates the fake component loader state on a successful component load
123   // request.
124   // |name|: the component name.
125   // |mount_requested|: whether the component should be mounted.
126   // |component_info|: the component's load information.
127   void FinishComponentLoad(const std::string& name,
128                            bool mount_requested,
129                            const ComponentInfo& component_info);
130 
131   // Whether the load requests should be queued up, and not handled immediately.
132   // When this is set, component load requests should be completed using
133   // FinishLoadRequest().
134   bool queue_load_requests_ = false;
135 
136   bool unload_component_result_ = true;
137 
138   // Set of components that can be handled by this component manager.
139   std::set<std::string> supported_components_;
140 
141   // Set of components registered with this component manager - used primarily
142   // by IsRegistered() implementation.
143   std::set<std::string> registered_components_;
144   base::Lock registered_components_lock_;
145 
146   // The component information registered using ResetComponentInfo() - used to
147   // handle component load requests when queue_load_requests_ is not set.
148   std::map<std::string, ComponentInfo> component_infos_;
149 
150   // List of pending component load requests per component. Used only if
151   // queue_load_requests_ is set.
152   std::map<std::string, std::list<LoadRequest>> pending_loads_;
153 
154   // Maps the currently installed (and loaded) components to their installation
155   // path.
156   std::map<std::string, base::FilePath> installed_components_;
157 
158   // Maps the currently mounted components to their mount point path.
159   std::map<std::string, base::FilePath> mounted_components_;
160 
161   DISALLOW_COPY_AND_ASSIGN(FakeCrOSComponentManager);
162 };
163 
164 }  // namespace component_updater
165 
166 #endif  // CHROME_BROWSER_COMPONENT_UPDATER_FAKE_CROS_COMPONENT_MANAGER_H_
167