blob: 6f884d46bd7b8b788a6766e5653e0d645863cef2 [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
Amin Hassaniec7bc112020-10-29 16:47:58 -070017#include "update_engine/aosp/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).
Alex Deymoebf6e122017-03-10 16:12:01 -080048const char kPropProductManufacturer[] = "ro.product.manufacturer";
49const char kPropBootHardwareSKU[] = "ro.boot.hardware.sku";
50const char kPropBootRevision[] = "ro.boot.revision";
Sen Jiang5011df62017-06-28 17:13:19 -070051const char kPropBuildDateUTC[] = "ro.build.date.utc";
Alex Deymoebf6e122017-03-10 16:12:01 -080052
Yifan Hongfd6640f2020-08-27 19:13:17 -070053string GetPartitionBuildDate(const string& partition_name) {
54 return android::base::GetProperty("ro." + partition_name + ".build.date.utc",
55 "");
56}
57
Yifan Hong70ba92e2020-09-22 23:56:00 +000058ErrorCode IsTimestampNewerLogged(const std::string& partition_name,
59 const std::string& old_version,
60 const std::string& new_version) {
61 auto error_code = utils::IsTimestampNewer(old_version, new_version);
62 if (error_code != ErrorCode::kSuccess) {
63 LOG(WARNING) << "Timestamp check failed with "
64 << utils::ErrorCodeToString(error_code) << ": "
65 << partition_name << " Partition timestamp: " << old_version
66 << " Update timestamp: " << new_version;
67 }
68 return error_code;
69}
70
Alex Deymofb905d92016-06-03 19:26:58 -070071} // namespace
72
Alex Deymo40d86b22015-09-03 22:27:10 -070073namespace hardware {
74
75// Factory defined in hardware.h.
76std::unique_ptr<HardwareInterface> CreateHardware() {
Ben Chanab5a0af2017-10-12 14:57:50 -070077 return std::make_unique<HardwareAndroid>();
Alex Deymo40d86b22015-09-03 22:27:10 -070078}
79
80} // namespace hardware
81
Alex Deymo1c4e84a2015-09-22 16:58:10 -070082// In Android there are normally three kinds of builds: eng, userdebug and user.
83// These builds target respectively a developer build, a debuggable version of
84// the final product and the pristine final product the end user will run.
85// Apart from the ro.build.type property name, they differ in the following
86// properties that characterize the builds:
87// * eng builds: ro.secure=0 and ro.debuggable=1
88// * userdebug builds: ro.secure=1 and ro.debuggable=1
89// * user builds: ro.secure=1 and ro.debuggable=0
90//
91// See IsOfficialBuild() and IsNormalMode() for the meaning of these options in
92// Android.
93
Alex Deymo40d86b22015-09-03 22:27:10 -070094bool HardwareAndroid::IsOfficialBuild() const {
Alex Deymo1c4e84a2015-09-22 16:58:10 -070095 // We run an official build iff ro.secure == 1, because we expect the build to
96 // behave like the end user product and check for updates. Note that while
97 // developers are able to build "official builds" by just running "make user",
98 // that will only result in a more restrictive environment. The important part
99 // is that we don't produce and push "non-official" builds to the end user.
100 //
101 // In case of a non-bool value, we take the most restrictive option and
102 // assume we are in an official-build.
Tom Cherryfadd03c2017-10-10 14:45:09 -0700103 return GetBoolProperty("ro.secure", true);
Alex Deymo40d86b22015-09-03 22:27:10 -0700104}
105
106bool HardwareAndroid::IsNormalBootMode() const {
Alex Deymo1c4e84a2015-09-22 16:58:10 -0700107 // We are running in "dev-mode" iff ro.debuggable == 1. In dev-mode the
108 // update_engine will allow extra developers options, such as providing a
109 // different update URL. In case of error, we assume the build is in
110 // normal-mode.
Tom Cherryfadd03c2017-10-10 14:45:09 -0700111 return !GetBoolProperty("ro.debuggable", false);
Alex Deymo40d86b22015-09-03 22:27:10 -0700112}
113
Sen Jiange67bb5b2016-06-20 15:53:56 -0700114bool HardwareAndroid::AreDevFeaturesEnabled() const {
115 return !IsNormalBootMode();
116}
117
Alex Deymo46a9aae2016-05-04 20:20:11 -0700118bool HardwareAndroid::IsOOBEEnabled() const {
119 // No OOBE flow blocking updates for Android-based boards.
120 return false;
121}
122
Alex Deymo40d86b22015-09-03 22:27:10 -0700123bool HardwareAndroid::IsOOBEComplete(base::Time* out_time_of_oobe) const {
Alex Deymo46a9aae2016-05-04 20:20:11 -0700124 LOG(WARNING) << "OOBE is not enabled but IsOOBEComplete() called.";
Alex Deymo4d2990d2015-09-15 12:11:26 -0700125 if (out_time_of_oobe)
126 *out_time_of_oobe = base::Time();
Alex Deymo40d86b22015-09-03 22:27:10 -0700127 return true;
128}
129
130string HardwareAndroid::GetHardwareClass() const {
Tom Cherryfadd03c2017-10-10 14:45:09 -0700131 auto manufacturer = GetProperty(kPropProductManufacturer, "");
132 auto sku = GetProperty(kPropBootHardwareSKU, "");
133 auto revision = GetProperty(kPropBootRevision, "");
Alex Deymoebf6e122017-03-10 16:12:01 -0800134
Tom Cherryfadd03c2017-10-10 14:45:09 -0700135 return manufacturer + ":" + sku + ":" + revision;
Alex Deymo40d86b22015-09-03 22:27:10 -0700136}
137
Matt Ziegelbaumaa8e1a42019-05-09 21:41:58 -0400138string HardwareAndroid::GetDeviceRequisition() const {
139 LOG(WARNING) << "STUB: Getting requisition is not supported.";
140 return "";
141}
142
Zentaro Kavanaghbaacb982018-02-20 17:48:39 -0800143int HardwareAndroid::GetMinKernelKeyVersion() const {
144 LOG(WARNING) << "STUB: No Kernel key version is available.";
145 return -1;
146}
147
Marton Hunyady99ced782018-05-08 12:59:50 +0200148int HardwareAndroid::GetMinFirmwareKeyVersion() const {
149 LOG(WARNING) << "STUB: No Firmware key version is available.";
150 return -1;
151}
152
Zentaro Kavanagh8f6f2432018-05-16 13:48:12 -0700153int HardwareAndroid::GetMaxFirmwareKeyRollforward() const {
154 LOG(WARNING) << "STUB: Getting firmware_max_rollforward is not supported.";
155 return -1;
156}
157
158bool HardwareAndroid::SetMaxFirmwareKeyRollforward(
159 int firmware_max_rollforward) {
160 LOG(WARNING) << "STUB: Setting firmware_max_rollforward is not supported.";
161 return false;
162}
163
Zentaro Kavanagh5d956152018-05-15 09:40:33 -0700164bool HardwareAndroid::SetMaxKernelKeyRollforward(int kernel_max_rollforward) {
165 LOG(WARNING) << "STUB: Setting kernel_max_rollforward is not supported.";
Zentaro Kavanaghbaacb982018-02-20 17:48:39 -0800166 return false;
167}
168
Alex Deymo40d86b22015-09-03 22:27:10 -0700169int HardwareAndroid::GetPowerwashCount() const {
170 LOG(WARNING) << "STUB: Assuming no factory reset was performed.";
171 return 0;
172}
173
Zentaro Kavanagh28def4f2019-01-15 17:15:01 -0800174bool HardwareAndroid::SchedulePowerwash(bool save_rollback_data) {
Alex Deymofb905d92016-06-03 19:26:58 -0700175 LOG(INFO) << "Scheduling a powerwash to BCB.";
Zentaro Kavanagh28def4f2019-01-15 17:15:01 -0800176 LOG_IF(WARNING, save_rollback_data) << "save_rollback_data was true but "
177 << "isn't supported.";
Sen Jiangd944faa2018-08-22 18:46:39 -0700178 string err;
179 if (!update_bootloader_message({"--wipe_data", "--reason=wipe_data_from_ota"},
180 &err)) {
181 LOG(ERROR) << "Failed to update bootloader message: " << err;
182 return false;
183 }
184 return true;
Alex Deymofb905d92016-06-03 19:26:58 -0700185}
186
187bool HardwareAndroid::CancelPowerwash() {
Sen Jiangd944faa2018-08-22 18:46:39 -0700188 string err;
189 if (!clear_bootloader_message(&err)) {
190 LOG(ERROR) << "Failed to clear bootloader message: " << err;
191 return false;
192 }
193 return true;
Alex Deymofb905d92016-06-03 19:26:58 -0700194}
195
Alex Deymodd132f32015-09-14 19:12:07 -0700196bool HardwareAndroid::GetNonVolatileDirectory(base::FilePath* path) const {
Sen Jiang9c123462015-11-19 13:16:23 -0800197 base::FilePath local_path(constants::kNonVolatileDirectory);
Kelvin Zhangd2822522020-07-07 17:20:58 -0400198 if (!base::DirectoryExists(local_path)) {
Alex Deymodd132f32015-09-14 19:12:07 -0700199 LOG(ERROR) << "Non-volatile directory not found: " << local_path.value();
200 return false;
201 }
202 *path = local_path;
203 return true;
204}
205
206bool HardwareAndroid::GetPowerwashSafeDirectory(base::FilePath* path) const {
207 // On Android, we don't have a directory persisted across powerwash.
208 return false;
209}
210
Sen Jiang5011df62017-06-28 17:13:19 -0700211int64_t HardwareAndroid::GetBuildTimestamp() const {
Tom Cherryfadd03c2017-10-10 14:45:09 -0700212 return GetIntProperty<int64_t>(kPropBuildDateUTC, 0);
Sen Jiang5011df62017-06-28 17:13:19 -0700213}
214
Tianjie Xu4ad3af62019-10-30 11:59:45 -0700215// Returns true if the device runs an userdebug build, and explicitly allows OTA
216// downgrade.
217bool HardwareAndroid::AllowDowngrade() const {
218 return GetBoolProperty("ro.ota.allow_downgrade", false) &&
219 GetBoolProperty("ro.debuggable", false);
220}
221
Amin Hassani1677e812017-06-21 13:36:36 -0700222bool HardwareAndroid::GetFirstActiveOmahaPingSent() const {
223 LOG(WARNING) << "STUB: Assuming first active omaha was never set.";
224 return false;
225}
226
Amin Hassani80f4d4c2018-05-16 13:34:00 -0700227bool HardwareAndroid::SetFirstActiveOmahaPingSent() {
228 LOG(WARNING) << "STUB: Assuming first active omaha is set.";
229 // We will set it true, so its failure doesn't cause escalation.
230 return true;
Amin Hassani1677e812017-06-21 13:36:36 -0700231}
232
Tianjie Xud6aa91f2019-11-14 11:55:10 -0800233void HardwareAndroid::SetWarmReset(bool warm_reset) {
Kelvin Zhanga22ef552020-10-12 19:03:52 -0400234 if constexpr (!constants::kIsRecovery) {
235 constexpr char warm_reset_prop[] = "ota.warm_reset";
236 if (!android::base::SetProperty(warm_reset_prop, warm_reset ? "1" : "0")) {
237 LOG(WARNING) << "Failed to set prop " << warm_reset_prop;
238 }
Tianjie Xud6aa91f2019-11-14 11:55:10 -0800239 }
240}
241
Yifan Hongfd6640f2020-08-27 19:13:17 -0700242string HardwareAndroid::GetVersionForLogging(
243 const string& partition_name) const {
244 if (partition_name == "boot") {
Yifan Hong70ba92e2020-09-22 23:56:00 +0000245 // ro.bootimage.build.date.utc
246 return GetPartitionBuildDate("bootimage");
Yifan Hongfd6640f2020-08-27 19:13:17 -0700247 }
248 return GetPartitionBuildDate(partition_name);
Kelvin Zhangd7191032020-08-11 10:48:16 -0400249}
250
Yifan Hong87029332020-09-01 17:20:08 -0700251ErrorCode HardwareAndroid::IsPartitionUpdateValid(
Yifan Hongfd6640f2020-08-27 19:13:17 -0700252 const string& partition_name, const string& new_version) const {
253 if (partition_name == "boot") {
Yifan Hong70ba92e2020-09-22 23:56:00 +0000254 const auto old_version = GetPartitionBuildDate("bootimage");
255 auto error_code =
256 IsTimestampNewerLogged(partition_name, old_version, new_version);
257 if (error_code == ErrorCode::kPayloadTimestampError) {
258 bool prevent_downgrade =
259 android::sysprop::GkiProperties::prevent_downgrade_version().value_or(
260 false);
261 if (!prevent_downgrade) {
262 LOG(WARNING) << "Downgrade of boot image is detected, but permitting "
263 "update because device does not prevent boot image "
264 "downgrade";
265 // If prevent_downgrade_version sysprop is not explicitly set, permit
266 // downgrade in boot image version.
267 // Even though error_code is overridden here, always call
268 // IsTimestampNewerLogged to produce log messages.
269 error_code = ErrorCode::kSuccess;
270 }
Yifan Hongfd6640f2020-08-27 19:13:17 -0700271 }
Yifan Hong70ba92e2020-09-22 23:56:00 +0000272 return error_code;
Yifan Hongfd6640f2020-08-27 19:13:17 -0700273 }
274
275 const auto old_version = GetPartitionBuildDate(partition_name);
Kelvin Zhangd7191032020-08-11 10:48:16 -0400276 // TODO(zhangkelvin) for some partitions, missing a current timestamp should
277 // be an error, e.g. system, vendor, product etc.
Yifan Hong70ba92e2020-09-22 23:56:00 +0000278 auto error_code =
279 IsTimestampNewerLogged(partition_name, old_version, new_version);
Yifan Hong87029332020-09-01 17:20:08 -0700280 return error_code;
Kelvin Zhangd7191032020-08-11 10:48:16 -0400281}
282
Alex Deymo40d86b22015-09-03 22:27:10 -0700283} // namespace chromeos_update_engine