blob: a12ae260693ec9ddcffa55094e0e018520b3cc51 [file] [log] [blame]
Xiaochu Liu1ccaed92018-06-13 14:19:55 -07001// 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 Hassanic4cc1ee2019-11-14 11:51:35 -08005#ifndef DLCSERVICE_DLC_SERVICE_H_
6#define DLCSERVICE_DLC_SERVICE_H_
Xiaochu Liu1ccaed92018-06-13 14:19:55 -07007
Xiaochu Liuc2b65f52018-07-20 12:47:05 -07008#include <memory>
Jae Hoon Kim013d58a2019-07-15 16:12:05 -07009#include <set>
Xiaochu Liu1ccaed92018-06-13 14:19:55 -070010#include <string>
Jae Hoon Kim7d0001e2021-07-07 13:04:40 -070011#include <utility>
Xiaochu Liud0184e32018-10-19 17:21:33 -070012#include <vector>
Xiaochu Liu1ccaed92018-06-13 14:19:55 -070013
Xiaochu Liuc2b65f52018-07-20 12:47:05 -070014#include <base/files/file_path.h>
Xiaochu Liu30067a62019-02-08 13:59:10 -080015#include <base/memory/weak_ptr.h>
Jae Hoon Kim53514af2020-07-27 11:50:26 -070016#include <base/optional.h>
Jae Hoon Kimb2baf582019-11-12 17:00:57 -080017#include <brillo/message_loops/message_loop.h>
Xiaochu Liu30067a62019-02-08 13:59:10 -080018#include <dlcservice/proto_bindings/dlcservice.pb.h>
Amin Hassaniaa38c792020-04-06 15:52:44 -070019#include <gtest/gtest_prod.h> // for FRIEND_TEST
Xiaochu Liuc2b65f52018-07-20 12:47:05 -070020#include <imageloader/dbus-proxies.h>
Amin Hassani7be4da42019-06-21 16:36:15 -070021#include <update_engine/proto_bindings/update_engine.pb.h>
Xiaochu Liu4cfdb052018-07-30 11:25:26 -070022#include <update_engine/dbus-proxies.h>
Xiaochu Liuc2b65f52018-07-20 12:47:05 -070023
Amin Hassani86649982020-03-31 16:03:37 -070024#include "dlcservice/dlc.h"
Jae Hoon Kim823ead32019-12-13 09:30:09 -080025#include "dlcservice/dlc_manager.h"
Jae Hoon Kimf4eed882020-01-28 17:29:16 -080026#include "dlcservice/system_state.h"
Xiaochu Liu1ccaed92018-06-13 14:19:55 -070027
28namespace dlcservice {
29
Amin Hassaniaa38c792020-04-06 15:52:44 -070030class DlcServiceInterface {
Xiaochu Liu1ccaed92018-06-13 14:19:55 -070031 public:
Amin Hassaniaa38c792020-04-06 15:52:44 -070032 virtual ~DlcServiceInterface() = default;
Xiaochu Liuc2b65f52018-07-20 12:47:05 -070033
Amin Hassanica3cbb72020-04-10 12:26:50 -070034 // Initializes the state of dlcservice.
35 virtual void Initialize() = 0;
Amin Hassani6d0367d2020-05-10 18:07:03 -070036 virtual bool Install(const DlcId& id,
Amin Hassaniaa38c792020-04-06 15:52:44 -070037 const std::string& omaha_url,
38 brillo::ErrorPtr* err) = 0;
Amin Hassani605988d2020-05-10 19:36:35 -070039 virtual bool Uninstall(const std::string& id, brillo::ErrorPtr* err) = 0;
40 virtual bool Purge(const std::string& id, brillo::ErrorPtr* err) = 0;
Amin Hassani1ac28312020-06-04 18:16:30 -070041 virtual const DlcBase* GetDlc(const DlcId& id, brillo::ErrorPtr* err) = 0;
Amin Hassani9ca846f2020-04-17 12:41:01 -070042 virtual DlcIdList GetInstalled() = 0;
Amin Hassanid5fc8b22020-04-29 12:44:52 -070043 virtual DlcIdList GetExistingDlcs() = 0;
Amin Hassani38f36792020-04-17 11:47:08 -070044 virtual DlcIdList GetDlcsToUpdate() = 0;
Amin Hassani605988d2020-05-10 19:36:35 -070045 virtual bool InstallCompleted(const DlcIdList& ids,
Jae Hoon Kim9a27d152020-04-10 12:50:14 -070046 brillo::ErrorPtr* err) = 0;
Amin Hassani605988d2020-05-10 19:36:35 -070047 virtual bool UpdateCompleted(const DlcIdList& ids, brillo::ErrorPtr* err) = 0;
Amin Hassaniaa38c792020-04-06 15:52:44 -070048};
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.
52class DlcService : public DlcServiceInterface {
53 public:
54 static const size_t kUECheckTimeout = 5;
55
56 DlcService();
Andrewf67a7812020-05-07 10:48:00 -070057 ~DlcService() override;
Amin Hassaniaa38c792020-04-06 15:52:44 -070058
Amin Hassanica3cbb72020-04-10 12:26:50 -070059 void Initialize() override;
Andrew0a534ed2020-05-06 09:59:17 -070060 // Calls |InstallInternal| and sends the metrics for unsuccessful installs.
Amin Hassani6d0367d2020-05-10 18:07:03 -070061 bool Install(const DlcId& id,
Amin Hassaniaa38c792020-04-06 15:52:44 -070062 const std::string& omaha_url,
63 brillo::ErrorPtr* err) override;
Amin Hassani605988d2020-05-10 19:36:35 -070064 bool Uninstall(const std::string& id, brillo::ErrorPtr* err) override;
65 bool Purge(const std::string& id, brillo::ErrorPtr* err) override;
Amin Hassani9ca846f2020-04-17 12:41:01 -070066 DlcIdList GetInstalled() override;
Amin Hassanid5fc8b22020-04-29 12:44:52 -070067 DlcIdList GetExistingDlcs() override;
Amin Hassani1ac28312020-06-04 18:16:30 -070068 const DlcBase* GetDlc(const DlcId& id, brillo::ErrorPtr* err) override;
Amin Hassani38f36792020-04-17 11:47:08 -070069 DlcIdList GetDlcsToUpdate() override;
Amin Hassani605988d2020-05-10 19:36:35 -070070 bool InstallCompleted(const DlcIdList& ids, brillo::ErrorPtr* err) override;
71 bool UpdateCompleted(const DlcIdList& ids, brillo::ErrorPtr* err) override;
Jae Hoon Kimc7beafd2019-07-22 18:14:47 -070072
Jae Hoon Kim7d0001e2021-07-07 13:04:40 -070073 void SetDlcManagerForTest(std::unique_ptr<DlcManagerInterface> dlc_manager) {
74 dlc_manager_ = std::move(dlc_manager);
75 }
76
Xiaochu Liuc2b65f52018-07-20 12:47:05 -070077 private:
Amin Hassaniaa38c792020-04-06 15:52:44 -070078 friend class DlcServiceTest;
Amin Hassani9a3f20c2020-05-25 16:38:33 -070079 FRIEND_TEST(DlcServiceTest, InstallCannotSetDlcActiveValue);
Amin Hassaniaa38c792020-04-06 15:52:44 -070080 FRIEND_TEST(DlcServiceTest, OnStatusUpdateSignalTest);
Amin Hassani6d0367d2020-05-10 18:07:03 -070081 FRIEND_TEST(DlcServiceTest, MountFailureTest);
Amin Hassaniaa38c792020-04-06 15:52:44 -070082 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 Hassaniaa38c792020-04-06 15:52:44 -070087 FRIEND_TEST(DlcServiceTest, OnStatusUpdateSignalDownloadProgressTest);
88 FRIEND_TEST(
89 DlcServiceTest,
90 OnStatusUpdateSignalSubsequentialBadOrNonInstalledDlcsNonBlocking);
Amin Hassanif656f292020-06-08 16:20:01 -070091 FRIEND_TEST(DlcServiceTest, PeriodicInstallCheck);
92 FRIEND_TEST(DlcServiceTest, InstallUpdateEngineBusyThenFreeTest);
93 FRIEND_TEST(DlcServiceTest, InstallSchedulesPeriodicInstallCheck);
Amin Hassani9a3f20c2020-05-25 16:38:33 -070094
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 Kim53514af2020-07-27 11:50:26 -0700101 // 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.
Andrewbcc4bd82020-06-11 14:23:55 -0700106 // The |err_in| argument is the error that causes the install to be cancelled.
107 void CancelInstall(const brillo::ErrorPtr& err_in);
Jae Hoon Kim1c9d8582019-10-14 10:52:05 -0700108
Amin Hassanif656f292020-06-08 16:20:01 -0700109 // 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 Kimc7beafd2019-07-22 18:14:47 -0700112
Jae Hoon Kim5f95ab92019-11-26 16:52:43 -0800113 // The periodic check that runs as a delayed task that checks update_engine
Amin Hassanif656f292020-06-08 16:20:01 -0700114 // 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 Kim5f95ab92019-11-26 16:52:43 -0800117 void PeriodicInstallCheck();
118
119 // Schedules the method |PeriodicInstallCheck()| to be ran at a later time,
Amin Hassanif656f292020-06-08 16:20:01 -0700120 void SchedulePeriodicInstallCheck();
Jae Hoon Kimb2baf582019-11-12 17:00:57 -0800121
Amin Hassanif656f292020-06-08 16:20:01 -0700122 // Gets update_engine's operation status and saves it in |SystemState|.
123 bool GetUpdateEngineStatus();
Xiaochu Liue9155842018-11-13 14:24:05 -0800124
Andrew0a534ed2020-05-06 09:59:17 -0700125 // 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 Hassaniaa38c792020-04-06 15:52:44 -0700130 // Called on receiving update_engine's |StatusUpdate| signal.
131 void OnStatusUpdateAdvancedSignal(
132 const update_engine::StatusResult& status_result);
133
Xiaochu Liu30067a62019-02-08 13:59:10 -0800134 // Called on being connected to update_engine's |StatusUpdate| signal.
Jae Hoon Kim80075fb2019-07-24 12:35:58 -0700135 void OnStatusUpdateAdvancedSignalConnected(const std::string& interface_name,
136 const std::string& signal_name,
137 bool success);
Xiaochu Liu30067a62019-02-08 13:59:10 -0800138
Amin Hassani759090b2020-04-13 12:31:10 -0700139 // 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 Kim53514af2020-07-27 11:50:26 -0700148 // Holds the DLC that is being installed by update_engine.
149 base::Optional<DlcId> installing_dlc_id_;
150
Jae Hoon Kim7d0001e2021-07-07 13:04:40 -0700151 std::unique_ptr<DlcManagerInterface> dlc_manager_;
Xiaochu Liuc2b65f52018-07-20 12:47:05 -0700152
Jae Hoon Kim5f95ab92019-11-26 16:52:43 -0800153 // Holds the ML task id of the delayed |PeriodicInstallCheck()| if an install
154 // is in progress.
Amin Hassanif656f292020-06-08 16:20:01 -0700155 brillo::MessageLoop::TaskId periodic_install_check_id_;
Jae Hoon Kim5f95ab92019-11-26 16:52:43 -0800156
Amin Hassanic4cc1ee2019-11-14 11:51:35 -0800157 base::WeakPtrFactory<DlcService> weak_ptr_factory_;
158
Amin Hassani6b010bf2020-06-04 17:26:58 -0700159 DlcService(const DlcService&) = delete;
160 DlcService& operator=(const DlcService&) = delete;
Xiaochu Liu1ccaed92018-06-13 14:19:55 -0700161};
162
163} // namespace dlcservice
164
Amin Hassanic4cc1ee2019-11-14 11:51:35 -0800165#endif // DLCSERVICE_DLC_SERVICE_H_