1 // 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 17 #include "update_engine/hardware_android.h" 18 19 #include <sys/types.h> 20 21 #include <memory> 22 23 #include <android-base/properties.h> 24 #include <base/files/file_util.h> 25 #include <bootloader_message/bootloader_message.h> 26 27 #include "update_engine/common/hardware.h" 28 #include "update_engine/common/platform_constants.h" 29 30 using android::base::GetBoolProperty; 31 using android::base::GetIntProperty; 32 using android::base::GetProperty; 33 using std::string; 34 35 namespace chromeos_update_engine { 36 37 namespace { 38 39 // Android properties that identify the hardware and potentially non-updatable 40 // parts of the bootloader (such as the bootloader version and the baseband 41 // version). 42 const char kPropBootBootloader[] = "ro.boot.bootloader"; 43 const char kPropBootBaseband[] = "ro.boot.baseband"; 44 const char kPropProductManufacturer[] = "ro.product.manufacturer"; 45 const char kPropBootHardwareSKU[] = "ro.boot.hardware.sku"; 46 const char kPropBootRevision[] = "ro.boot.revision"; 47 const char kPropBuildDateUTC[] = "ro.build.date.utc"; 48 49 } // namespace 50 51 namespace hardware { 52 53 // Factory defined in hardware.h. 54 std::unique_ptr<HardwareInterface> CreateHardware() { 55 return std::make_unique<HardwareAndroid>(); 56 } 57 58 } // namespace hardware 59 60 // In Android there are normally three kinds of builds: eng, userdebug and user. 61 // These builds target respectively a developer build, a debuggable version of 62 // the final product and the pristine final product the end user will run. 63 // Apart from the ro.build.type property name, they differ in the following 64 // properties that characterize the builds: 65 // * eng builds: ro.secure=0 and ro.debuggable=1 66 // * userdebug builds: ro.secure=1 and ro.debuggable=1 67 // * user builds: ro.secure=1 and ro.debuggable=0 68 // 69 // See IsOfficialBuild() and IsNormalMode() for the meaning of these options in 70 // Android. 71 72 bool HardwareAndroid::IsOfficialBuild() const { 73 // We run an official build iff ro.secure == 1, because we expect the build to 74 // behave like the end user product and check for updates. Note that while 75 // developers are able to build "official builds" by just running "make user", 76 // that will only result in a more restrictive environment. The important part 77 // is that we don't produce and push "non-official" builds to the end user. 78 // 79 // In case of a non-bool value, we take the most restrictive option and 80 // assume we are in an official-build. 81 return GetBoolProperty("ro.secure", true); 82 } 83 84 bool HardwareAndroid::IsNormalBootMode() const { 85 // We are running in "dev-mode" iff ro.debuggable == 1. In dev-mode the 86 // update_engine will allow extra developers options, such as providing a 87 // different update URL. In case of error, we assume the build is in 88 // normal-mode. 89 return !GetBoolProperty("ro.debuggable", false); 90 } 91 92 bool HardwareAndroid::AreDevFeaturesEnabled() const { 93 return !IsNormalBootMode(); 94 } 95 96 bool HardwareAndroid::IsOOBEEnabled() const { 97 // No OOBE flow blocking updates for Android-based boards. 98 return false; 99 } 100 101 bool HardwareAndroid::IsOOBEComplete(base::Time* out_time_of_oobe) const { 102 LOG(WARNING) << "OOBE is not enabled but IsOOBEComplete() called."; 103 if (out_time_of_oobe) 104 *out_time_of_oobe = base::Time(); 105 return true; 106 } 107 108 string HardwareAndroid::GetHardwareClass() const { 109 auto manufacturer = GetProperty(kPropProductManufacturer, ""); 110 auto sku = GetProperty(kPropBootHardwareSKU, ""); 111 auto revision = GetProperty(kPropBootRevision, ""); 112 113 return manufacturer + ":" + sku + ":" + revision; 114 } 115 116 string HardwareAndroid::GetFirmwareVersion() const { 117 return GetProperty(kPropBootBootloader, ""); 118 } 119 120 string HardwareAndroid::GetECVersion() const { 121 return GetProperty(kPropBootBaseband, ""); 122 } 123 124 int HardwareAndroid::GetMinKernelKeyVersion() const { 125 LOG(WARNING) << "STUB: No Kernel key version is available."; 126 return -1; 127 } 128 129 int HardwareAndroid::GetMinFirmwareKeyVersion() const { 130 LOG(WARNING) << "STUB: No Firmware key version is available."; 131 return -1; 132 } 133 134 int HardwareAndroid::GetMaxFirmwareKeyRollforward() const { 135 LOG(WARNING) << "STUB: Getting firmware_max_rollforward is not supported."; 136 return -1; 137 } 138 139 bool HardwareAndroid::SetMaxFirmwareKeyRollforward( 140 int firmware_max_rollforward) { 141 LOG(WARNING) << "STUB: Setting firmware_max_rollforward is not supported."; 142 return false; 143 } 144 145 bool HardwareAndroid::SetMaxKernelKeyRollforward(int kernel_max_rollforward) { 146 LOG(WARNING) << "STUB: Setting kernel_max_rollforward is not supported."; 147 return false; 148 } 149 150 int HardwareAndroid::GetPowerwashCount() const { 151 LOG(WARNING) << "STUB: Assuming no factory reset was performed."; 152 return 0; 153 } 154 155 bool HardwareAndroid::SchedulePowerwash(bool is_rollback) { 156 LOG(INFO) << "Scheduling a powerwash to BCB."; 157 LOG_IF(WARNING, is_rollback) << "is_rollback was true but isn't supported."; 158 string err; 159 if (!update_bootloader_message({"--wipe_data", "--reason=wipe_data_from_ota"}, 160 &err)) { 161 LOG(ERROR) << "Failed to update bootloader message: " << err; 162 return false; 163 } 164 return true; 165 } 166 167 bool HardwareAndroid::CancelPowerwash() { 168 string err; 169 if (!clear_bootloader_message(&err)) { 170 LOG(ERROR) << "Failed to clear bootloader message: " << err; 171 return false; 172 } 173 return true; 174 } 175 176 bool HardwareAndroid::GetNonVolatileDirectory(base::FilePath* path) const { 177 base::FilePath local_path(constants::kNonVolatileDirectory); 178 if (!base::PathExists(local_path)) { 179 LOG(ERROR) << "Non-volatile directory not found: " << local_path.value(); 180 return false; 181 } 182 *path = local_path; 183 return true; 184 } 185 186 bool HardwareAndroid::GetPowerwashSafeDirectory(base::FilePath* path) const { 187 // On Android, we don't have a directory persisted across powerwash. 188 return false; 189 } 190 191 int64_t HardwareAndroid::GetBuildTimestamp() const { 192 return GetIntProperty<int64_t>(kPropBuildDateUTC, 0); 193 } 194 195 // Returns true if the device runs an userdebug build, and explicitly allows OTA 196 // downgrade. 197 bool HardwareAndroid::AllowDowngrade() const { 198 return GetBoolProperty("ro.ota.allow_downgrade", false) && 199 GetBoolProperty("ro.debuggable", false); 200 } 201 202 bool HardwareAndroid::GetFirstActiveOmahaPingSent() const { 203 LOG(WARNING) << "STUB: Assuming first active omaha was never set."; 204 return false; 205 } 206 207 bool HardwareAndroid::SetFirstActiveOmahaPingSent() { 208 LOG(WARNING) << "STUB: Assuming first active omaha is set."; 209 // We will set it true, so its failure doesn't cause escalation. 210 return true; 211 } 212 213 void HardwareAndroid::SetWarmReset(bool warm_reset) { 214 constexpr char warm_reset_prop[] = "ota.warm_reset"; 215 if (!android::base::SetProperty(warm_reset_prop, warm_reset ? "1" : "0")) { 216 LOG(WARNING) << "Failed to set prop " << warm_reset_prop; 217 } 218 } 219 220 } // namespace chromeos_update_engine 221