firmware_update_manager.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. // Copyright 2021 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. #ifndef ASH_COMPONENTS_FWUPD_FIRMWARE_UPDATE_MANAGER_H_
  5. #define ASH_COMPONENTS_FWUPD_FIRMWARE_UPDATE_MANAGER_H_
  6. #include <string>
  7. #include "ash/webui/firmware_update_ui/mojom/firmware_update.mojom.h"
  8. #include "base/callback.h"
  9. #include "base/component_export.h"
  10. #include "base/containers/flat_map.h"
  11. #include "base/containers/flat_set.h"
  12. #include "base/files/file.h"
  13. #include "base/files/file_path.h"
  14. #include "base/files/scoped_file.h"
  15. #include "base/memory/weak_ptr.h"
  16. #include "base/observer_list.h"
  17. #include "base/observer_list_types.h"
  18. #include "base/task/sequenced_task_runner.h"
  19. #include "chromeos/ash/components/dbus/fwupd/fwupd_client.h"
  20. #include "chromeos/ash/components/dbus/fwupd/fwupd_device.h"
  21. #include "chromeos/ash/components/dbus/fwupd/fwupd_properties.h"
  22. #include "chromeos/ash/components/dbus/fwupd/fwupd_update.h"
  23. #include "mojo/public/cpp/bindings/pending_receiver.h"
  24. #include "mojo/public/cpp/bindings/receiver.h"
  25. #include "mojo/public/cpp/bindings/remote_set.h"
  26. namespace network {
  27. class SimpleURLLoader;
  28. } // namespace network
  29. namespace ash {
  30. // FirmwareUpdateManager contains all logic that runs the firmware update SWA.
  31. class COMPONENT_EXPORT(ASH_FIRMWARE_UPDATE_MANAGER) FirmwareUpdateManager
  32. : public FwupdClient::Observer,
  33. public firmware_update::mojom::UpdateProvider,
  34. public firmware_update::mojom::InstallController {
  35. public:
  36. FirmwareUpdateManager();
  37. FirmwareUpdateManager(const FirmwareUpdateManager&) = delete;
  38. FirmwareUpdateManager& operator=(const FirmwareUpdateManager&) = delete;
  39. ~FirmwareUpdateManager() override;
  40. class Observer : public base::CheckedObserver {
  41. public:
  42. ~Observer() override = default;
  43. // Called to notify observers, primarily notification controllers, that a
  44. // critical firmware update is available.
  45. virtual void OnFirmwareUpdateReceived() = 0;
  46. };
  47. // Returns true if the global instance is initialized.
  48. static bool IsInitialized();
  49. void AddObserver(Observer* observer);
  50. void RemoveObserver(Observer* observer);
  51. // firmware_update::mojom::UpdateProvider
  52. void ObservePeripheralUpdates(
  53. mojo::PendingRemote<firmware_update::mojom::UpdateObserver> observer)
  54. override;
  55. void PrepareForUpdate(const std::string& device_id,
  56. PrepareForUpdateCallback callback) override;
  57. void FetchInProgressUpdate(FetchInProgressUpdateCallback callback) override;
  58. // firmware_update::mojom::InstallController
  59. void BeginUpdate(const std::string& device_id,
  60. const base::FilePath& filepath) override;
  61. void AddObserver(
  62. mojo::PendingRemote<firmware_update::mojom::UpdateProgressObserver>
  63. observer) override;
  64. // Gets the global instance pointer.
  65. static FirmwareUpdateManager* Get();
  66. // Gets the number of cached updates.
  67. size_t GetUpdateCount() { return updates_.size(); }
  68. // FwupdClient::Observer:
  69. // When the fwupd DBus client gets a response with devices from fwupd,
  70. // it calls this function and passes the response.
  71. void OnDeviceListResponse(FwupdDeviceList* devices) override;
  72. // When the fwupd DBus client gets a response with updates from fwupd,
  73. // it calls this function and passes the response.
  74. void OnUpdateListResponse(const std::string& device_id,
  75. FwupdUpdateList* updates) override;
  76. void OnInstallResponse(bool success) override;
  77. // TODO(jimmyxgong): Implement this function to send property updates via
  78. // mojo.
  79. void OnPropertiesChangedResponse(FwupdProperties* properties) override;
  80. // Query all updates for all devices.
  81. void RequestAllUpdates();
  82. // TODO(jimmyxgong): This should override the mojo api interface.
  83. // Download and prepare the install file for a specific device.
  84. void StartInstall(const std::string& device_id,
  85. const base::FilePath& filepath,
  86. base::OnceCallback<void()> callback);
  87. void BindInterface(
  88. mojo::PendingReceiver<firmware_update::mojom::UpdateProvider>
  89. pending_receiver);
  90. void set_should_show_notification_for_test(bool show_notification) {
  91. should_show_notification_for_test_ = show_notification;
  92. }
  93. protected:
  94. friend class FirmwareUpdateManagerTest;
  95. // Temporary auxiliary variables for testing.
  96. // TODO(swifton): Replace with mock observers.
  97. int on_device_list_response_count_for_testing_ = 0;
  98. int on_update_list_response_count_for_testing_ = 0;
  99. private:
  100. friend class FirmwareUpdateManagerTest;
  101. // Query the fwupd DBus client for currently connected devices.
  102. void RequestDevices();
  103. // Query the fwupd DBus client for updates for a certain device.
  104. void RequestUpdates(const std::string& device_id);
  105. // Callback handler after fetching the file descriptor.
  106. void OnGetFileDescriptor(const std::string& device_id,
  107. FirmwareInstallOptions options,
  108. base::OnceCallback<void()> callback,
  109. base::ScopedFD file_descriptor);
  110. // Query the fwupd DBus client to install an update for a certain device.
  111. void InstallUpdate(const std::string& device_id,
  112. FirmwareInstallOptions options,
  113. base::OnceCallback<void()> callback,
  114. base::File patch_file);
  115. void CreateLocalPatchFile(const base::FilePath& cache_path,
  116. const std::string& device_id,
  117. const base::FilePath& filepath,
  118. base::OnceCallback<void()> callback);
  119. void MaybeDownloadFileToInternal(const base::FilePath& patch_path,
  120. const std::string& device_id,
  121. const base::FilePath& filepath,
  122. base::OnceCallback<void()> callback,
  123. bool write_file_success);
  124. void DownloadFileToInternal(const base::FilePath& patch_path,
  125. const std::string& device_id,
  126. const base::FilePath& filepath,
  127. base::OnceCallback<void()> callback);
  128. void OnUrlDownloadedToFile(
  129. const std::string& device_id,
  130. std::unique_ptr<network::SimpleURLLoader> simple_loader,
  131. base::OnceCallback<void()> callback,
  132. base::FilePath download_path);
  133. // Notifies observers registered with ObservePeripheralUpdates() the current
  134. // list of devices with pending updates (if any).
  135. void NotifyUpdateListObservers();
  136. bool HasPendingUpdates();
  137. void SetFakeUrlForTesting(const std::string& fake_url) {
  138. fake_url_for_testing_ = fake_url;
  139. }
  140. // Resets the mojo::Receiver |install_controller_receiver_|
  141. // and |update_progress_observer_|.
  142. void ResetInstallState();
  143. // Checks if any update in |updates_| is critical. If so,
  144. // a single notification is shown to the user.
  145. void ShowNotificationIfRequired();
  146. // Call to notify observers that a new notification is needed.
  147. void NotifyCriticalFirmwareUpdateReceived();
  148. // Records the # of devices found at startup and whenever the device list
  149. // is refreshed.
  150. void RecordDeviceMetrics(int num_devices);
  151. // Records the # of updates found at startup and whenever the update list
  152. // is refreshed.
  153. void RecordUpdateMetrics();
  154. int GetNumCriticalUpdates();
  155. // Map of a device ID to `FwupdDevice` which is waiting for the list
  156. // of updates.
  157. base::flat_map<std::string, FwupdDevice> devices_pending_update_;
  158. // Set of device IDs with critical updates that we've already shown a
  159. // notification for.
  160. base::flat_set<std::string> devices_already_notified_;
  161. // List of all available updates. If `devices_pending_update_` is not
  162. // empty then this list is not yet complete.
  163. std::vector<firmware_update::mojom::FirmwareUpdatePtr> updates_;
  164. // Only used for testing if StartInstall() queries to a fake URL.
  165. std::string fake_url_for_testing_;
  166. // The device update that is currently inflight.
  167. firmware_update::mojom::FirmwareUpdatePtr inflight_update_;
  168. // Used to show the firmware update notification and to determine which
  169. // metric to fire (Startup/Refresh).
  170. bool is_first_response_ = true;
  171. // Whether or not fetching updates in inflight.
  172. bool is_fetching_updates_ = false;
  173. // Used only for testing to force notification to appear.
  174. bool should_show_notification_for_test_ = false;
  175. // Remotes for tracking observers that will be notified of changes to the
  176. // list of firmware updates.
  177. mojo::RemoteSet<firmware_update::mojom::UpdateObserver>
  178. update_list_observers_;
  179. // Remote for tracking observer that will be notified of changes to
  180. // the in-progress update.
  181. mojo::Remote<firmware_update::mojom::UpdateProgressObserver>
  182. update_progress_observer_;
  183. base::ObserverList<Observer> observer_list_;
  184. scoped_refptr<base::SequencedTaskRunner> task_runner_;
  185. mojo::Receiver<firmware_update::mojom::UpdateProvider> receiver_{this};
  186. mojo::Receiver<firmware_update::mojom::InstallController>
  187. install_controller_receiver_{this};
  188. base::WeakPtrFactory<FirmwareUpdateManager> weak_ptr_factory_{this};
  189. };
  190. } // namespace ash
  191. #endif // ASH_COMPONENTS_FWUPD_FIRMWARE_UPDATE_MANAGER_H_