blob: a659bf672afa0760a2d894e504162875140cb601 [file] [log] [blame]
Alex Deymo40d86b22015-09-03 22:27:10 -07001//
2// Copyright (C) 2015 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
Alex Deymo1b03f9f2015-12-09 00:38:36 -080017#include "update_engine/hardware_android.h"
Alex Deymo40d86b22015-09-03 22:27:10 -070018
Alex Deymofb905d92016-06-03 19:26:58 -070019#include <sys/types.h>
20
Tom Cherryfadd03c2017-10-10 14:45:09 -070021#include <memory>
Kelvin Zhangd7191032020-08-11 10:48:16 -040022#include <string>
23#include <string_view>
Alex Deymofb905d92016-06-03 19:26:58 -070024
Yifan Hong126d13e2020-09-21 19:50:06 -070025#include <android/sysprop/GkiProperties.sysprop.h>
Kelvin Zhangd7191032020-08-11 10:48:16 -040026#include <android-base/parseint.h>
Tom Cherryfadd03c2017-10-10 14:45:09 -070027#include <android-base/properties.h>
Alex Deymodd132f32015-09-14 19:12:07 -070028#include <base/files/file_util.h>
Tao Bao304680c2018-03-31 10:36:52 -070029#include <bootloader_message/bootloader_message.h>
Alex Deymo40d86b22015-09-03 22:27:10 -070030
Yifan Hong87029332020-09-01 17:20:08 -070031#include "update_engine/common/error_code_utils.h"
Alex Deymo39910dc2015-11-09 17:04:30 -080032#include "update_engine/common/hardware.h"
Sen Jiang9c123462015-11-19 13:16:23 -080033#include "update_engine/common/platform_constants.h"
Kelvin Zhangd7191032020-08-11 10:48:16 -040034#include "update_engine/common/utils.h"
Alex Deymo40d86b22015-09-03 22:27:10 -070035
Tom Cherryfadd03c2017-10-10 14:45:09 -070036using android::base::GetBoolProperty;
37using android::base::GetIntProperty;
38using android::base::GetProperty;
Alex Deymo40d86b22015-09-03 22:27:10 -070039using std::string;
40
41namespace chromeos_update_engine {
42
Alex Deymofb905d92016-06-03 19:26:58 -070043namespace {
44
Alex Deymoebf6e122017-03-10 16:12:01 -080045// Android properties that identify the hardware and potentially non-updatable
46// parts of the bootloader (such as the bootloader version and the baseband
47// version).
48const char kPropBootBootloader[] = "ro.boot.bootloader";
49const char kPropBootBaseband[] = "ro.boot.baseband";
50const char kPropProductManufacturer[] = "ro.product.manufacturer";
51const char kPropBootHardwareSKU[] = "ro.boot.hardware.sku";
52const char kPropBootRevision[] = "ro.boot.revision";
Sen Jiang5011df62017-06-28 17:13:19 -070053const char kPropBuildDateUTC[] = "ro.build.date.utc";
Alex Deymoebf6e122017-03-10 16:12:01 -080054
Yifan Hongfd6640f2020-08-27 19:13:17 -070055string GetPartitionBuildDate(const string& partition_name) {
56 return android::base::GetProperty("ro." + partition_name + ".build.date.utc",
57 "");
58}
59
Yifan Hong70ba92e2020-09-22 23:56:00 +000060ErrorCode IsTimestampNewerLogged(const std::string& partition_name,
61 const std::string& old_version,
62 const std::string& new_version) {
63 auto error_code = utils::IsTimestampNewer(old_version, new_version);
64 if (error_code != ErrorCode::kSuccess) {
65 LOG(WARNING) << "Timestamp check failed with "
66 << utils::ErrorCodeToString(error_code) << ": "
67 << partition_name << " Partition timestamp: " << old_version
68 << " Update timestamp: " << new_version;
69 }
70 return error_code;
71}
72
Alex Deymofb905d92016-06-03 19:26:58 -070073} // namespace
74
Alex Deymo40d86b22015-09-03 22:27:10 -070075namespace hardware {
76
77// Factory defined in hardware.h.
78std::unique_ptr<HardwareInterface> CreateHardware() {
Ben Chanab5a0af2017-10-12 14:57:50 -070079 return std::make_unique<HardwareAndroid>();
Alex Deymo40d86b22015-09-03 22:27:10 -070080}
81
82} // namespace hardware
83
Alex Deymo1c4e84a2015-09-22 16:58:10 -070084// In Android there are normally three kinds of builds: eng, userdebug and user.
85// These builds target respectively a developer build, a debuggable version of
86// the final product and the pristine final product the end user will run.
87// Apart from the ro.build.type property name, they differ in the following
88// properties that characterize the builds:
89// * eng builds: ro.secure=0 and ro.debuggable=1
90// * userdebug builds: ro.secure=1 and ro.debuggable=1
91// * user builds: ro.secure=1 and ro.debuggable=0
92//
93// See IsOfficialBuild() and IsNormalMode() for the meaning of these options in
94// Android.
95
Alex Deymo40d86b22015-09-03 22:27:10 -070096bool HardwareAndroid::IsOfficialBuild() const {
Alex Deymo1c4e84a2015-09-22 16:58:10 -070097 // We run an official build iff ro.secure == 1, because we expect the build to
98 // behave like the end user product and check for updates. Note that while
99 // developers are able to build "official builds" by just running "make user",
100 // that will only result in a more restrictive environment. The important part
101 // is that we don't produce and push "non-official" builds to the end user.
102 //
103 // In case of a non-bool value, we take the most restrictive option and
104 // assume we are in an official-build.
Tom Cherryfadd03c2017-10-10 14:45:09 -0700105 return GetBoolProperty("ro.secure", true);
Alex Deymo40d86b22015-09-03 22:27:10 -0700106}
107
108bool HardwareAndroid::IsNormalBootMode() const {
Alex Deymo1c4e84a2015-09-22 16:58:10 -0700109 // We are running in "dev-mode" iff ro.debuggable == 1. In dev-mode the
110 // update_engine will allow extra developers options, such as providing a
111 // different update URL. In case of error, we assume the build is in
112 // normal-mode.
Tom Cherryfadd03c2017-10-10 14:45:09 -0700113 return !GetBoolProperty("ro.debuggable", false);
Alex Deymo40d86b22015-09-03 22:27:10 -0700114}
115
Sen Jiange67bb5b2016-06-20 15:53:56 -0700116bool HardwareAndroid::AreDevFeaturesEnabled() const {
117 return !IsNormalBootMode();
118}
119
Alex Deymo46a9aae2016-05-04 20:20:11 -0700120bool HardwareAndroid::IsOOBEEnabled() const {
121 // No OOBE flow blocking updates for Android-based boards.
122 return false;
123}
124
Alex Deymo40d86b22015-09-03 22:27:10 -0700125bool HardwareAndroid::IsOOBEComplete(base::Time* out_time_of_oobe) const {
Alex Deymo46a9aae2016-05-04 20:20:11 -0700126 LOG(WARNING) << "OOBE is not enabled but IsOOBEComplete() called.";
Alex Deymo4d2990d2015-09-15 12:11:26 -0700127 if (out_time_of_oobe)
128 *out_time_of_oobe = base::Time();
Alex Deymo40d86b22015-09-03 22:27:10 -0700129 return true;
130}
131
132string HardwareAndroid::GetHardwareClass() const {
Tom Cherryfadd03c2017-10-10 14:45:09 -0700133 auto manufacturer = GetProperty(kPropProductManufacturer, "");
134 auto sku = GetProperty(kPropBootHardwareSKU, "");
135 auto revision = GetProperty(kPropBootRevision, "");
Alex Deymoebf6e122017-03-10 16:12:01 -0800136
Tom Cherryfadd03c2017-10-10 14:45:09 -0700137 return manufacturer + ":" + sku + ":" + revision;
Alex Deymo40d86b22015-09-03 22:27:10 -0700138}
139
140string HardwareAndroid::GetFirmwareVersion() const {
Tom Cherryfadd03c2017-10-10 14:45:09 -0700141 return GetProperty(kPropBootBootloader, "");
Alex Deymo40d86b22015-09-03 22:27:10 -0700142}
143
144string HardwareAndroid::GetECVersion() const {
Tom Cherryfadd03c2017-10-10 14:45:09 -0700145 return GetProperty(kPropBootBaseband, "");
Alex Deymo40d86b22015-09-03 22:27:10 -0700146}
147
Matt Ziegelbaumaa8e1a42019-05-09 21:41:58 -0400148string HardwareAndroid::GetDeviceRequisition() const {
149 LOG(WARNING) << "STUB: Getting requisition is not supported.";
150 return "";
151}
152
Zentaro Kavanaghbaacb982018-02-20 17:48:39 -0800153int HardwareAndroid::GetMinKernelKeyVersion() const {
154 LOG(WARNING) << "STUB: No Kernel key version is available.";
155 return -1;
156}
157
Marton Hunyady99ced782018-05-08 12:59:50 +0200158int HardwareAndroid::GetMinFirmwareKeyVersion() const {
159 LOG(WARNING) << "STUB: No Firmware key version is available.";
160 return -1;
161}
162
Zentaro Kavanagh8f6f2432018-05-16 13:48:12 -0700163int HardwareAndroid::GetMaxFirmwareKeyRollforward() const {
164 LOG(WARNING) << "STUB: Getting firmware_max_rollforward is not supported.";
165 return -1;
166}
167
168bool HardwareAndroid::SetMaxFirmwareKeyRollforward(
169 int firmware_max_rollforward) {
170 LOG(WARNING) << "STUB: Setting firmware_max_rollforward is not supported.";
171 return false;
172}
173
Zentaro Kavanagh5d956152018-05-15 09:40:33 -0700174bool HardwareAndroid::SetMaxKernelKeyRollforward(int kernel_max_rollforward) {
175 LOG(WARNING) << "STUB: Setting kernel_max_rollforward is not supported.";
Zentaro Kavanaghbaacb982018-02-20 17:48:39 -0800176 return false;
177}
178
Alex Deymo40d86b22015-09-03 22:27:10 -0700179int HardwareAndroid::GetPowerwashCount() const {
180 LOG(WARNING) << "STUB: Assuming no factory reset was performed.";
181 return 0;
182}
183
Zentaro Kavanagh28def4f2019-01-15 17:15:01 -0800184bool HardwareAndroid::SchedulePowerwash(bool save_rollback_data) {
Alex Deymofb905d92016-06-03 19:26:58 -0700185 LOG(INFO) << "Scheduling a powerwash to BCB.";
Zentaro Kavanagh28def4f2019-01-15 17:15:01 -0800186 LOG_IF(WARNING, save_rollback_data) << "save_rollback_data was true but "
187 << "isn't supported.";
Sen Jiangd944faa2018-08-22 18:46:39 -0700188 string err;
189 if (!update_bootloader_message({"--wipe_data", "--reason=wipe_data_from_ota"},
190 &err)) {
191 LOG(ERROR) << "Failed to update bootloader message: " << err;
192 return false;
193 }
194 return true;
Alex Deymofb905d92016-06-03 19:26:58 -0700195}
196
197bool HardwareAndroid::CancelPowerwash() {
Sen Jiangd944faa2018-08-22 18:46:39 -0700198 string err;
199 if (!clear_bootloader_message(&err)) {
200 LOG(ERROR) << "Failed to clear bootloader message: " << err;
201 return false;
202 }
203 return true;
Alex Deymofb905d92016-06-03 19:26:58 -0700204}
205
Alex Deymodd132f32015-09-14 19:12:07 -0700206bool HardwareAndroid::GetNonVolatileDirectory(base::FilePath* path) const {
Sen Jiang9c123462015-11-19 13:16:23 -0800207 base::FilePath local_path(constants::kNonVolatileDirectory);
Kelvin Zhangd2822522020-07-07 17:20:58 -0400208 if (!base::DirectoryExists(local_path)) {
Alex Deymodd132f32015-09-14 19:12:07 -0700209 LOG(ERROR) << "Non-volatile directory not found: " << local_path.value();
210 return false;
211 }
212 *path = local_path;
213 return true;
214}
215
216bool HardwareAndroid::GetPowerwashSafeDirectory(base::FilePath* path) const {
217 // On Android, we don't have a directory persisted across powerwash.
218 return false;
219}
220
Sen Jiang5011df62017-06-28 17:13:19 -0700221int64_t HardwareAndroid::GetBuildTimestamp() const {
Tom Cherryfadd03c2017-10-10 14:45:09 -0700222 return GetIntProperty<int64_t>(kPropBuildDateUTC, 0);
Sen Jiang5011df62017-06-28 17:13:19 -0700223}
224
Tianjie Xu4ad3af62019-10-30 11:59:45 -0700225// Returns true if the device runs an userdebug build, and explicitly allows OTA
226// downgrade.
227bool HardwareAndroid::AllowDowngrade() const {
228 return GetBoolProperty("ro.ota.allow_downgrade", false) &&
229 GetBoolProperty("ro.debuggable", false);
230}
231
Amin Hassani1677e812017-06-21 13:36:36 -0700232bool HardwareAndroid::GetFirstActiveOmahaPingSent() const {
233 LOG(WARNING) << "STUB: Assuming first active omaha was never set.";
234 return false;
235}
236
Amin Hassani80f4d4c2018-05-16 13:34:00 -0700237bool HardwareAndroid::SetFirstActiveOmahaPingSent() {
238 LOG(WARNING) << "STUB: Assuming first active omaha is set.";
239 // We will set it true, so its failure doesn't cause escalation.
240 return true;
Amin Hassani1677e812017-06-21 13:36:36 -0700241}
242
Tianjie Xud6aa91f2019-11-14 11:55:10 -0800243void HardwareAndroid::SetWarmReset(bool warm_reset) {
244 constexpr char warm_reset_prop[] = "ota.warm_reset";
245 if (!android::base::SetProperty(warm_reset_prop, warm_reset ? "1" : "0")) {
246 LOG(WARNING) << "Failed to set prop " << warm_reset_prop;
247 }
248}
249
Yifan Hongfd6640f2020-08-27 19:13:17 -0700250string HardwareAndroid::GetVersionForLogging(
251 const string& partition_name) const {
252 if (partition_name == "boot") {
Yifan Hong70ba92e2020-09-22 23:56:00 +0000253 // ro.bootimage.build.date.utc
254 return GetPartitionBuildDate("bootimage");
Yifan Hongfd6640f2020-08-27 19:13:17 -0700255 }
256 return GetPartitionBuildDate(partition_name);
Kelvin Zhangd7191032020-08-11 10:48:16 -0400257}
258
Yifan Hong87029332020-09-01 17:20:08 -0700259ErrorCode HardwareAndroid::IsPartitionUpdateValid(
Yifan Hongfd6640f2020-08-27 19:13:17 -0700260 const string& partition_name, const string& new_version) const {
261 if (partition_name == "boot") {
Yifan Hong70ba92e2020-09-22 23:56:00 +0000262 const auto old_version = GetPartitionBuildDate("bootimage");
263 auto error_code =
264 IsTimestampNewerLogged(partition_name, old_version, new_version);
265 if (error_code == ErrorCode::kPayloadTimestampError) {
266 bool prevent_downgrade =
267 android::sysprop::GkiProperties::prevent_downgrade_version().value_or(
268 false);
269 if (!prevent_downgrade) {
270 LOG(WARNING) << "Downgrade of boot image is detected, but permitting "
271 "update because device does not prevent boot image "
272 "downgrade";
273 // If prevent_downgrade_version sysprop is not explicitly set, permit
274 // downgrade in boot image version.
275 // Even though error_code is overridden here, always call
276 // IsTimestampNewerLogged to produce log messages.
277 error_code = ErrorCode::kSuccess;
278 }
Yifan Hongfd6640f2020-08-27 19:13:17 -0700279 }
Yifan Hong70ba92e2020-09-22 23:56:00 +0000280 return error_code;
Yifan Hongfd6640f2020-08-27 19:13:17 -0700281 }
282
283 const auto old_version = GetPartitionBuildDate(partition_name);
Kelvin Zhangd7191032020-08-11 10:48:16 -0400284 // TODO(zhangkelvin) for some partitions, missing a current timestamp should
285 // be an error, e.g. system, vendor, product etc.
Yifan Hong70ba92e2020-09-22 23:56:00 +0000286 auto error_code =
287 IsTimestampNewerLogged(partition_name, old_version, new_version);
Yifan Hong87029332020-09-01 17:20:08 -0700288 return error_code;
Kelvin Zhangd7191032020-08-11 10:48:16 -0400289}
290
Alex Deymo40d86b22015-09-03 22:27:10 -0700291} // namespace chromeos_update_engine