Xiaochu Liu | 1ccaed9 | 2018-06-13 14:19:55 -0700 | [diff] [blame] | 1 | // Copyright 2018 The Chromium OS 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 | |
Amin Hassani | c4cc1ee | 2019-11-14 11:51:35 -0800 | [diff] [blame] | 5 | #ifndef DLCSERVICE_DLC_SERVICE_H_ |
| 6 | #define DLCSERVICE_DLC_SERVICE_H_ |
Xiaochu Liu | 1ccaed9 | 2018-06-13 14:19:55 -0700 | [diff] [blame] | 7 | |
Xiaochu Liu | c2b65f5 | 2018-07-20 12:47:05 -0700 | [diff] [blame] | 8 | #include <memory> |
Jae Hoon Kim | 013d58a | 2019-07-15 16:12:05 -0700 | [diff] [blame] | 9 | #include <set> |
Xiaochu Liu | 1ccaed9 | 2018-06-13 14:19:55 -0700 | [diff] [blame] | 10 | #include <string> |
Jae Hoon Kim | 7d0001e | 2021-07-07 13:04:40 -0700 | [diff] [blame] | 11 | #include <utility> |
Xiaochu Liu | d0184e3 | 2018-10-19 17:21:33 -0700 | [diff] [blame] | 12 | #include <vector> |
Xiaochu Liu | 1ccaed9 | 2018-06-13 14:19:55 -0700 | [diff] [blame] | 13 | |
Xiaochu Liu | c2b65f5 | 2018-07-20 12:47:05 -0700 | [diff] [blame] | 14 | #include <base/files/file_path.h> |
Xiaochu Liu | 30067a6 | 2019-02-08 13:59:10 -0800 | [diff] [blame] | 15 | #include <base/memory/weak_ptr.h> |
Jae Hoon Kim | 53514af | 2020-07-27 11:50:26 -0700 | [diff] [blame] | 16 | #include <base/optional.h> |
Jae Hoon Kim | b2baf58 | 2019-11-12 17:00:57 -0800 | [diff] [blame] | 17 | #include <brillo/message_loops/message_loop.h> |
Xiaochu Liu | 30067a6 | 2019-02-08 13:59:10 -0800 | [diff] [blame] | 18 | #include <dlcservice/proto_bindings/dlcservice.pb.h> |
Amin Hassani | aa38c79 | 2020-04-06 15:52:44 -0700 | [diff] [blame] | 19 | #include <gtest/gtest_prod.h> // for FRIEND_TEST |
Xiaochu Liu | c2b65f5 | 2018-07-20 12:47:05 -0700 | [diff] [blame] | 20 | #include <imageloader/dbus-proxies.h> |
Amin Hassani | 7be4da4 | 2019-06-21 16:36:15 -0700 | [diff] [blame] | 21 | #include <update_engine/proto_bindings/update_engine.pb.h> |
Xiaochu Liu | 4cfdb05 | 2018-07-30 11:25:26 -0700 | [diff] [blame] | 22 | #include <update_engine/dbus-proxies.h> |
Xiaochu Liu | c2b65f5 | 2018-07-20 12:47:05 -0700 | [diff] [blame] | 23 | |
Amin Hassani | 8664998 | 2020-03-31 16:03:37 -0700 | [diff] [blame] | 24 | #include "dlcservice/dlc.h" |
Jae Hoon Kim | 823ead3 | 2019-12-13 09:30:09 -0800 | [diff] [blame] | 25 | #include "dlcservice/dlc_manager.h" |
Jae Hoon Kim | f4eed88 | 2020-01-28 17:29:16 -0800 | [diff] [blame] | 26 | #include "dlcservice/system_state.h" |
Xiaochu Liu | 1ccaed9 | 2018-06-13 14:19:55 -0700 | [diff] [blame] | 27 | |
| 28 | namespace dlcservice { |
| 29 | |
Amin Hassani | aa38c79 | 2020-04-06 15:52:44 -0700 | [diff] [blame] | 30 | class DlcServiceInterface { |
Xiaochu Liu | 1ccaed9 | 2018-06-13 14:19:55 -0700 | [diff] [blame] | 31 | public: |
Amin Hassani | aa38c79 | 2020-04-06 15:52:44 -0700 | [diff] [blame] | 32 | virtual ~DlcServiceInterface() = default; |
Xiaochu Liu | c2b65f5 | 2018-07-20 12:47:05 -0700 | [diff] [blame] | 33 | |
Amin Hassani | ca3cbb7 | 2020-04-10 12:26:50 -0700 | [diff] [blame] | 34 | // Initializes the state of dlcservice. |
| 35 | virtual void Initialize() = 0; |
Amin Hassani | 6d0367d | 2020-05-10 18:07:03 -0700 | [diff] [blame] | 36 | virtual bool Install(const DlcId& id, |
Amin Hassani | aa38c79 | 2020-04-06 15:52:44 -0700 | [diff] [blame] | 37 | const std::string& omaha_url, |
| 38 | brillo::ErrorPtr* err) = 0; |
Amin Hassani | 605988d | 2020-05-10 19:36:35 -0700 | [diff] [blame] | 39 | virtual bool Uninstall(const std::string& id, brillo::ErrorPtr* err) = 0; |
| 40 | virtual bool Purge(const std::string& id, brillo::ErrorPtr* err) = 0; |
Amin Hassani | 1ac2831 | 2020-06-04 18:16:30 -0700 | [diff] [blame] | 41 | virtual const DlcBase* GetDlc(const DlcId& id, brillo::ErrorPtr* err) = 0; |
Amin Hassani | 9ca846f | 2020-04-17 12:41:01 -0700 | [diff] [blame] | 42 | virtual DlcIdList GetInstalled() = 0; |
Amin Hassani | d5fc8b2 | 2020-04-29 12:44:52 -0700 | [diff] [blame] | 43 | virtual DlcIdList GetExistingDlcs() = 0; |
Amin Hassani | 38f3679 | 2020-04-17 11:47:08 -0700 | [diff] [blame] | 44 | virtual DlcIdList GetDlcsToUpdate() = 0; |
Amin Hassani | 605988d | 2020-05-10 19:36:35 -0700 | [diff] [blame] | 45 | virtual bool InstallCompleted(const DlcIdList& ids, |
Jae Hoon Kim | 9a27d15 | 2020-04-10 12:50:14 -0700 | [diff] [blame] | 46 | brillo::ErrorPtr* err) = 0; |
Amin Hassani | 605988d | 2020-05-10 19:36:35 -0700 | [diff] [blame] | 47 | virtual bool UpdateCompleted(const DlcIdList& ids, brillo::ErrorPtr* err) = 0; |
Amin Hassani | aa38c79 | 2020-04-06 15:52:44 -0700 | [diff] [blame] | 48 | }; |
| 49 | |
| 50 | // DlcService manages life-cycles of DLCs (Downloadable Content) and provides an |
| 51 | // API for the rest of the system to install/uninstall DLCs. |
| 52 | class DlcService : public DlcServiceInterface { |
| 53 | public: |
| 54 | static const size_t kUECheckTimeout = 5; |
| 55 | |
| 56 | DlcService(); |
Andrew | f67a781 | 2020-05-07 10:48:00 -0700 | [diff] [blame] | 57 | ~DlcService() override; |
Amin Hassani | aa38c79 | 2020-04-06 15:52:44 -0700 | [diff] [blame] | 58 | |
Amin Hassani | ca3cbb7 | 2020-04-10 12:26:50 -0700 | [diff] [blame] | 59 | void Initialize() override; |
Andrew | 0a534ed | 2020-05-06 09:59:17 -0700 | [diff] [blame] | 60 | // Calls |InstallInternal| and sends the metrics for unsuccessful installs. |
Amin Hassani | 6d0367d | 2020-05-10 18:07:03 -0700 | [diff] [blame] | 61 | bool Install(const DlcId& id, |
Amin Hassani | aa38c79 | 2020-04-06 15:52:44 -0700 | [diff] [blame] | 62 | const std::string& omaha_url, |
| 63 | brillo::ErrorPtr* err) override; |
Amin Hassani | 605988d | 2020-05-10 19:36:35 -0700 | [diff] [blame] | 64 | bool Uninstall(const std::string& id, brillo::ErrorPtr* err) override; |
| 65 | bool Purge(const std::string& id, brillo::ErrorPtr* err) override; |
Amin Hassani | 9ca846f | 2020-04-17 12:41:01 -0700 | [diff] [blame] | 66 | DlcIdList GetInstalled() override; |
Amin Hassani | d5fc8b2 | 2020-04-29 12:44:52 -0700 | [diff] [blame] | 67 | DlcIdList GetExistingDlcs() override; |
Amin Hassani | 1ac2831 | 2020-06-04 18:16:30 -0700 | [diff] [blame] | 68 | const DlcBase* GetDlc(const DlcId& id, brillo::ErrorPtr* err) override; |
Amin Hassani | 38f3679 | 2020-04-17 11:47:08 -0700 | [diff] [blame] | 69 | DlcIdList GetDlcsToUpdate() override; |
Amin Hassani | 605988d | 2020-05-10 19:36:35 -0700 | [diff] [blame] | 70 | bool InstallCompleted(const DlcIdList& ids, brillo::ErrorPtr* err) override; |
| 71 | bool UpdateCompleted(const DlcIdList& ids, brillo::ErrorPtr* err) override; |
Jae Hoon Kim | c7beafd | 2019-07-22 18:14:47 -0700 | [diff] [blame] | 72 | |
Jae Hoon Kim | 7d0001e | 2021-07-07 13:04:40 -0700 | [diff] [blame] | 73 | void SetDlcManagerForTest(std::unique_ptr<DlcManagerInterface> dlc_manager) { |
| 74 | dlc_manager_ = std::move(dlc_manager); |
| 75 | } |
| 76 | |
Xiaochu Liu | c2b65f5 | 2018-07-20 12:47:05 -0700 | [diff] [blame] | 77 | private: |
Amin Hassani | aa38c79 | 2020-04-06 15:52:44 -0700 | [diff] [blame] | 78 | friend class DlcServiceTest; |
Amin Hassani | 9a3f20c | 2020-05-25 16:38:33 -0700 | [diff] [blame] | 79 | FRIEND_TEST(DlcServiceTest, InstallCannotSetDlcActiveValue); |
Amin Hassani | aa38c79 | 2020-04-06 15:52:44 -0700 | [diff] [blame] | 80 | FRIEND_TEST(DlcServiceTest, OnStatusUpdateSignalTest); |
Amin Hassani | 6d0367d | 2020-05-10 18:07:03 -0700 | [diff] [blame] | 81 | FRIEND_TEST(DlcServiceTest, MountFailureTest); |
Amin Hassani | aa38c79 | 2020-04-06 15:52:44 -0700 | [diff] [blame] | 82 | FRIEND_TEST(DlcServiceTest, OnStatusUpdateSignalDlcRootTest); |
| 83 | FRIEND_TEST(DlcServiceTest, OnStatusUpdateSignalNoRemountTest); |
| 84 | FRIEND_TEST(DlcServiceTest, ReportingFailureCleanupTest); |
| 85 | FRIEND_TEST(DlcServiceTest, ReportingFailureSignalTest); |
| 86 | FRIEND_TEST(DlcServiceTest, ProbableUpdateEngineRestartCleanupTest); |
Amin Hassani | aa38c79 | 2020-04-06 15:52:44 -0700 | [diff] [blame] | 87 | FRIEND_TEST(DlcServiceTest, OnStatusUpdateSignalDownloadProgressTest); |
| 88 | FRIEND_TEST( |
| 89 | DlcServiceTest, |
| 90 | OnStatusUpdateSignalSubsequentialBadOrNonInstalledDlcsNonBlocking); |
Amin Hassani | f656f29 | 2020-06-08 16:20:01 -0700 | [diff] [blame] | 91 | FRIEND_TEST(DlcServiceTest, PeriodicInstallCheck); |
| 92 | FRIEND_TEST(DlcServiceTest, InstallUpdateEngineBusyThenFreeTest); |
| 93 | FRIEND_TEST(DlcServiceTest, InstallSchedulesPeriodicInstallCheck); |
Amin Hassani | 9a3f20c | 2020-05-25 16:38:33 -0700 | [diff] [blame] | 94 | |
| 95 | // Install the DLC with ID |id| through update_engine by sending a request to |
| 96 | // it. |
| 97 | bool InstallWithUpdateEngine(const DlcId& id, |
| 98 | const std::string& omaha_url, |
| 99 | brillo::ErrorPtr* err); |
| 100 | |
Jae Hoon Kim | 53514af | 2020-07-27 11:50:26 -0700 | [diff] [blame] | 101 | // Finishes the currently running installation. Returns true if the |
| 102 | // installation finished successfully, false otherwise. |
| 103 | bool FinishInstall(brillo::ErrorPtr* err); |
| 104 | |
| 105 | // Cancels the currently running installation. |
Andrew | bcc4bd8 | 2020-06-11 14:23:55 -0700 | [diff] [blame] | 106 | // The |err_in| argument is the error that causes the install to be cancelled. |
| 107 | void CancelInstall(const brillo::ErrorPtr& err_in); |
Jae Hoon Kim | 1c9d858 | 2019-10-14 10:52:05 -0700 | [diff] [blame] | 108 | |
Amin Hassani | f656f29 | 2020-06-08 16:20:01 -0700 | [diff] [blame] | 109 | // Handles status result from update_engine. Returns true if the installation |
| 110 | // is going fine, false otherwise. |
| 111 | bool HandleStatusResult(brillo::ErrorPtr* err); |
Jae Hoon Kim | c7beafd | 2019-07-22 18:14:47 -0700 | [diff] [blame] | 112 | |
Jae Hoon Kim | 5f95ab9 | 2019-11-26 16:52:43 -0800 | [diff] [blame] | 113 | // The periodic check that runs as a delayed task that checks update_engine |
Amin Hassani | f656f29 | 2020-06-08 16:20:01 -0700 | [diff] [blame] | 114 | // status during an install to make sure update_engine is active. This is |
| 115 | // basically a fallback mechanism in case we miss some of the update_engine's |
| 116 | // signals so we don't block forever. |
Jae Hoon Kim | 5f95ab9 | 2019-11-26 16:52:43 -0800 | [diff] [blame] | 117 | void PeriodicInstallCheck(); |
| 118 | |
| 119 | // Schedules the method |PeriodicInstallCheck()| to be ran at a later time, |
Amin Hassani | f656f29 | 2020-06-08 16:20:01 -0700 | [diff] [blame] | 120 | void SchedulePeriodicInstallCheck(); |
Jae Hoon Kim | b2baf58 | 2019-11-12 17:00:57 -0800 | [diff] [blame] | 121 | |
Amin Hassani | f656f29 | 2020-06-08 16:20:01 -0700 | [diff] [blame] | 122 | // Gets update_engine's operation status and saves it in |SystemState|. |
| 123 | bool GetUpdateEngineStatus(); |
Xiaochu Liu | e915584 | 2018-11-13 14:24:05 -0800 | [diff] [blame] | 124 | |
Andrew | 0a534ed | 2020-05-06 09:59:17 -0700 | [diff] [blame] | 125 | // Installs a DLC without sending metrics when the install fails. |
| 126 | bool InstallInternal(const DlcId& id, |
| 127 | const std::string& omaha_url, |
| 128 | brillo::ErrorPtr* err); |
| 129 | |
Amin Hassani | aa38c79 | 2020-04-06 15:52:44 -0700 | [diff] [blame] | 130 | // Called on receiving update_engine's |StatusUpdate| signal. |
| 131 | void OnStatusUpdateAdvancedSignal( |
| 132 | const update_engine::StatusResult& status_result); |
| 133 | |
Xiaochu Liu | 30067a6 | 2019-02-08 13:59:10 -0800 | [diff] [blame] | 134 | // Called on being connected to update_engine's |StatusUpdate| signal. |
Jae Hoon Kim | 80075fb | 2019-07-24 12:35:58 -0700 | [diff] [blame] | 135 | void OnStatusUpdateAdvancedSignalConnected(const std::string& interface_name, |
| 136 | const std::string& signal_name, |
| 137 | bool success); |
Xiaochu Liu | 30067a6 | 2019-02-08 13:59:10 -0800 | [diff] [blame] | 138 | |
Amin Hassani | 759090b | 2020-04-13 12:31:10 -0700 | [diff] [blame] | 139 | // Called when we are connected to the session_manager's |SessionStateChanged| |
| 140 | // signal. |
| 141 | void OnSessionStateChangedSignalConnected(const std::string& interface_name, |
| 142 | const std::string& signal_name, |
| 143 | bool success); |
| 144 | |
| 145 | // Called when the session state changes (user logs in or logs out). |
| 146 | void OnSessionStateChangedSignal(const std::string& state); |
| 147 | |
Jae Hoon Kim | 53514af | 2020-07-27 11:50:26 -0700 | [diff] [blame] | 148 | // Holds the DLC that is being installed by update_engine. |
| 149 | base::Optional<DlcId> installing_dlc_id_; |
| 150 | |
Jae Hoon Kim | 7d0001e | 2021-07-07 13:04:40 -0700 | [diff] [blame] | 151 | std::unique_ptr<DlcManagerInterface> dlc_manager_; |
Xiaochu Liu | c2b65f5 | 2018-07-20 12:47:05 -0700 | [diff] [blame] | 152 | |
Jae Hoon Kim | 5f95ab9 | 2019-11-26 16:52:43 -0800 | [diff] [blame] | 153 | // Holds the ML task id of the delayed |PeriodicInstallCheck()| if an install |
| 154 | // is in progress. |
Amin Hassani | f656f29 | 2020-06-08 16:20:01 -0700 | [diff] [blame] | 155 | brillo::MessageLoop::TaskId periodic_install_check_id_; |
Jae Hoon Kim | 5f95ab9 | 2019-11-26 16:52:43 -0800 | [diff] [blame] | 156 | |
Amin Hassani | c4cc1ee | 2019-11-14 11:51:35 -0800 | [diff] [blame] | 157 | base::WeakPtrFactory<DlcService> weak_ptr_factory_; |
| 158 | |
Amin Hassani | 6b010bf | 2020-06-04 17:26:58 -0700 | [diff] [blame] | 159 | DlcService(const DlcService&) = delete; |
| 160 | DlcService& operator=(const DlcService&) = delete; |
Xiaochu Liu | 1ccaed9 | 2018-06-13 14:19:55 -0700 | [diff] [blame] | 161 | }; |
| 162 | |
| 163 | } // namespace dlcservice |
| 164 | |
Amin Hassani | c4cc1ee | 2019-11-14 11:51:35 -0800 | [diff] [blame] | 165 | #endif // DLCSERVICE_DLC_SERVICE_H_ |