1 /*
2  * Copyright (C) 2017 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 agree 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 <stdio.h>
18 #include <sys/stat.h>
19 #include <sys/types.h>
20 #include <unistd.h>
21 
22 #include <algorithm>
23 #include <random>
24 #include <string>
25 #include <vector>
26 
27 #include <android-base/file.h>
28 #include <android-base/properties.h>
29 #include <android-base/strings.h>
30 #include <gtest/gtest.h>
31 #include <vintf/VintfObjectRecovery.h>
32 #include <ziparchive/zip_archive.h>
33 #include <ziparchive/zip_writer.h>
34 
35 #include "install/install.h"
36 #include "otautil/paths.h"
37 #include "private/setup_commands.h"
38 
BuildZipArchive(const std::map<std::string,std::string> & file_map,int fd,int compression_type)39 static void BuildZipArchive(const std::map<std::string, std::string>& file_map, int fd,
40                             int compression_type) {
41   FILE* zip_file = fdopen(fd, "w");
42   ZipWriter writer(zip_file);
43   for (const auto& [name, content] : file_map) {
44     ASSERT_EQ(0, writer.StartEntry(name.c_str(), compression_type));
45     ASSERT_EQ(0, writer.WriteBytes(content.data(), content.size()));
46     ASSERT_EQ(0, writer.FinishEntry());
47   }
48   ASSERT_EQ(0, writer.Finish());
49   ASSERT_EQ(0, fclose(zip_file));
50 }
51 
TEST(InstallTest,verify_package_compatibility_no_entry)52 TEST(InstallTest, verify_package_compatibility_no_entry) {
53   TemporaryFile temp_file;
54   // The archive must have something to be opened correctly.
55   BuildZipArchive({ { "dummy_entry", "" } }, temp_file.release(), kCompressStored);
56 
57   // Doesn't contain compatibility zip entry.
58   ZipArchiveHandle zip;
59   ASSERT_EQ(0, OpenArchive(temp_file.path, &zip));
60   ASSERT_TRUE(verify_package_compatibility(zip));
61   CloseArchive(zip);
62 }
63 
TEST(InstallTest,verify_package_compatibility_invalid_entry)64 TEST(InstallTest, verify_package_compatibility_invalid_entry) {
65   TemporaryFile temp_file;
66   BuildZipArchive({ { "compatibility.zip", "" } }, temp_file.release(), kCompressStored);
67 
68   // Empty compatibility zip entry.
69   ZipArchiveHandle zip;
70   ASSERT_EQ(0, OpenArchive(temp_file.path, &zip));
71   ASSERT_FALSE(verify_package_compatibility(zip));
72   CloseArchive(zip);
73 }
74 
TEST(InstallTest,read_metadata_from_package_smoke)75 TEST(InstallTest, read_metadata_from_package_smoke) {
76   TemporaryFile temp_file;
77   const std::string content("abc=defg");
78   BuildZipArchive({ { "META-INF/com/android/metadata", content } }, temp_file.release(),
79                   kCompressStored);
80 
81   ZipArchiveHandle zip;
82   ASSERT_EQ(0, OpenArchive(temp_file.path, &zip));
83   std::map<std::string, std::string> metadata;
84   ASSERT_TRUE(ReadMetadataFromPackage(zip, &metadata));
85   ASSERT_EQ("defg", metadata["abc"]);
86   CloseArchive(zip);
87 
88   TemporaryFile temp_file2;
89   BuildZipArchive({ { "META-INF/com/android/metadata", content } }, temp_file2.release(),
90                   kCompressDeflated);
91 
92   ASSERT_EQ(0, OpenArchive(temp_file2.path, &zip));
93   metadata.clear();
94   ASSERT_TRUE(ReadMetadataFromPackage(zip, &metadata));
95   ASSERT_EQ("defg", metadata["abc"]);
96   CloseArchive(zip);
97 }
98 
TEST(InstallTest,read_metadata_from_package_no_entry)99 TEST(InstallTest, read_metadata_from_package_no_entry) {
100   TemporaryFile temp_file;
101   BuildZipArchive({ { "dummy_entry", "" } }, temp_file.release(), kCompressStored);
102 
103   ZipArchiveHandle zip;
104   ASSERT_EQ(0, OpenArchive(temp_file.path, &zip));
105   std::map<std::string, std::string> metadata;
106   ASSERT_FALSE(ReadMetadataFromPackage(zip, &metadata));
107   CloseArchive(zip);
108 }
109 
TEST(InstallTest,read_wipe_ab_partition_list)110 TEST(InstallTest, read_wipe_ab_partition_list) {
111   std::vector<std::string> partition_list = {
112     "/dev/block/bootdevice/by-name/system_a", "/dev/block/bootdevice/by-name/system_b",
113     "/dev/block/bootdevice/by-name/vendor_a", "/dev/block/bootdevice/by-name/vendor_b",
114     "/dev/block/bootdevice/by-name/userdata", "# Wipe the boot partitions last",
115     "/dev/block/bootdevice/by-name/boot_a",   "/dev/block/bootdevice/by-name/boot_b",
116   };
117   TemporaryFile temp_file;
118   BuildZipArchive({ { "recovery.wipe", android::base::Join(partition_list, '\n') } },
119                   temp_file.release(), kCompressDeflated);
120   std::string wipe_package;
121   ASSERT_TRUE(android::base::ReadFileToString(temp_file.path, &wipe_package));
122 
123   auto package = Package::CreateMemoryPackage(
124       std::vector<uint8_t>(wipe_package.begin(), wipe_package.end()), nullptr);
125 
126   auto read_partition_list = GetWipePartitionList(package.get());
127   std::vector<std::string> expected = {
128     "/dev/block/bootdevice/by-name/system_a", "/dev/block/bootdevice/by-name/system_b",
129     "/dev/block/bootdevice/by-name/vendor_a", "/dev/block/bootdevice/by-name/vendor_b",
130     "/dev/block/bootdevice/by-name/userdata", "/dev/block/bootdevice/by-name/boot_a",
131     "/dev/block/bootdevice/by-name/boot_b",
132   };
133   ASSERT_EQ(expected, read_partition_list);
134 }
135 
TEST(InstallTest,verify_package_compatibility_with_libvintf_malformed_xml)136 TEST(InstallTest, verify_package_compatibility_with_libvintf_malformed_xml) {
137   TemporaryFile compatibility_zip_file;
138   std::string malformed_xml = "malformed";
139   BuildZipArchive({ { "system_manifest.xml", malformed_xml } }, compatibility_zip_file.release(),
140                   kCompressDeflated);
141 
142   TemporaryFile temp_file;
143   std::string compatibility_zip_content;
144   ASSERT_TRUE(
145       android::base::ReadFileToString(compatibility_zip_file.path, &compatibility_zip_content));
146   BuildZipArchive({ { "compatibility.zip", compatibility_zip_content } }, temp_file.release(),
147                   kCompressStored);
148 
149   ZipArchiveHandle zip;
150   ASSERT_EQ(0, OpenArchive(temp_file.path, &zip));
151   std::vector<std::string> compatibility_info;
152   compatibility_info.push_back(malformed_xml);
153   // Malformed compatibility zip is expected to be rejected by libvintf. But we defer that to
154   // libvintf.
155   std::string err;
156   bool result =
157       android::vintf::VintfObjectRecovery::CheckCompatibility(compatibility_info, &err) == 0;
158   ASSERT_EQ(result, verify_package_compatibility(zip));
159   CloseArchive(zip);
160 }
161 
TEST(InstallTest,verify_package_compatibility_with_libvintf_system_manifest_xml)162 TEST(InstallTest, verify_package_compatibility_with_libvintf_system_manifest_xml) {
163   static constexpr const char* system_manifest_xml_path = "/system/manifest.xml";
164   if (access(system_manifest_xml_path, R_OK) == -1) {
165     GTEST_LOG_(INFO) << "Test skipped on devices w/o /system/manifest.xml.";
166     return;
167   }
168   std::string system_manifest_xml_content;
169   ASSERT_TRUE(
170       android::base::ReadFileToString(system_manifest_xml_path, &system_manifest_xml_content));
171   TemporaryFile compatibility_zip_file;
172   BuildZipArchive({ { "system_manifest.xml", system_manifest_xml_content } },
173                   compatibility_zip_file.release(), kCompressDeflated);
174 
175   TemporaryFile temp_file;
176   std::string compatibility_zip_content;
177   ASSERT_TRUE(
178       android::base::ReadFileToString(compatibility_zip_file.path, &compatibility_zip_content));
179   BuildZipArchive({ { "compatibility.zip", compatibility_zip_content } }, temp_file.release(),
180                   kCompressStored);
181 
182   ZipArchiveHandle zip;
183   ASSERT_EQ(0, OpenArchive(temp_file.path, &zip));
184   std::vector<std::string> compatibility_info;
185   compatibility_info.push_back(system_manifest_xml_content);
186   std::string err;
187   bool result =
188       android::vintf::VintfObjectRecovery::CheckCompatibility(compatibility_info, &err) == 0;
189   // Make sure the result is consistent with libvintf library.
190   ASSERT_EQ(result, verify_package_compatibility(zip));
191   CloseArchive(zip);
192 }
193 
TEST(InstallTest,SetUpNonAbUpdateCommands)194 TEST(InstallTest, SetUpNonAbUpdateCommands) {
195   TemporaryFile temp_file;
196   static constexpr const char* UPDATE_BINARY_NAME = "META-INF/com/google/android/update-binary";
197   BuildZipArchive({ { UPDATE_BINARY_NAME, "" } }, temp_file.release(), kCompressStored);
198 
199   ZipArchiveHandle zip;
200   ASSERT_EQ(0, OpenArchive(temp_file.path, &zip));
201   int status_fd = 10;
202   std::string package = "/path/to/update.zip";
203   TemporaryDir td;
204   std::string binary_path = std::string(td.path) + "/update_binary";
205   Paths::Get().set_temporary_update_binary(binary_path);
206   std::vector<std::string> cmd;
207   ASSERT_EQ(0, SetUpNonAbUpdateCommands(package, zip, 0, status_fd, &cmd));
208   ASSERT_EQ(4U, cmd.size());
209   ASSERT_EQ(binary_path, cmd[0]);
210   ASSERT_EQ("3", cmd[1]);  // RECOVERY_API_VERSION
211   ASSERT_EQ(std::to_string(status_fd), cmd[2]);
212   ASSERT_EQ(package, cmd[3]);
213   struct stat sb;
214   ASSERT_EQ(0, stat(binary_path.c_str(), &sb));
215   ASSERT_EQ(static_cast<mode_t>(0755), sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));
216 
217   // With non-zero retry count. update_binary will be removed automatically.
218   cmd.clear();
219   ASSERT_EQ(0, SetUpNonAbUpdateCommands(package, zip, 2, status_fd, &cmd));
220   ASSERT_EQ(5U, cmd.size());
221   ASSERT_EQ(binary_path, cmd[0]);
222   ASSERT_EQ("3", cmd[1]);  // RECOVERY_API_VERSION
223   ASSERT_EQ(std::to_string(status_fd), cmd[2]);
224   ASSERT_EQ(package, cmd[3]);
225   ASSERT_EQ("retry", cmd[4]);
226   sb = {};
227   ASSERT_EQ(0, stat(binary_path.c_str(), &sb));
228   ASSERT_EQ(static_cast<mode_t>(0755), sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));
229 
230   CloseArchive(zip);
231 }
232 
TEST(InstallTest,SetUpNonAbUpdateCommands_MissingUpdateBinary)233 TEST(InstallTest, SetUpNonAbUpdateCommands_MissingUpdateBinary) {
234   TemporaryFile temp_file;
235   // The archive must have something to be opened correctly.
236   BuildZipArchive({ { "dummy_entry", "" } }, temp_file.release(), kCompressStored);
237 
238   // Missing update binary.
239   ZipArchiveHandle zip;
240   ASSERT_EQ(0, OpenArchive(temp_file.path, &zip));
241   int status_fd = 10;
242   std::string package = "/path/to/update.zip";
243   TemporaryDir td;
244   Paths::Get().set_temporary_update_binary(std::string(td.path) + "/update_binary");
245   std::vector<std::string> cmd;
246   ASSERT_EQ(INSTALL_CORRUPT, SetUpNonAbUpdateCommands(package, zip, 0, status_fd, &cmd));
247   CloseArchive(zip);
248 }
249 
VerifyAbUpdateCommands(const std::string & serialno,bool success=true)250 static void VerifyAbUpdateCommands(const std::string& serialno, bool success = true) {
251   TemporaryFile temp_file;
252 
253   const std::string properties = "some_properties";
254   std::string device = android::base::GetProperty("ro.product.device", "");
255   ASSERT_NE("", device);
256   std::string timestamp = android::base::GetProperty("ro.build.date.utc", "");
257   ASSERT_NE("", timestamp);
258 
259   std::vector<std::string> meta{ "ota-type=AB", "pre-device=" + device,
260                                  "post-timestamp=" + timestamp };
261   if (!serialno.empty()) {
262     meta.push_back("serialno=" + serialno);
263   }
264   std::string metadata_string = android::base::Join(meta, "\n");
265 
266   BuildZipArchive({ { "payload.bin", "" },
267                     { "payload_properties.txt", properties },
268                     { "META-INF/com/android/metadata", metadata_string } },
269                   temp_file.release(), kCompressStored);
270 
271   ZipArchiveHandle zip;
272   ASSERT_EQ(0, OpenArchive(temp_file.path, &zip));
273   ZipString payload_name("payload.bin");
274   ZipEntry payload_entry;
275   ASSERT_EQ(0, FindEntry(zip, payload_name, &payload_entry));
276 
277   std::map<std::string, std::string> metadata;
278   ASSERT_TRUE(ReadMetadataFromPackage(zip, &metadata));
279   if (success) {
280     ASSERT_EQ(0, CheckPackageMetadata(metadata, OtaType::AB));
281 
282     int status_fd = 10;
283     std::string package = "/path/to/update.zip";
284     std::vector<std::string> cmd;
285     ASSERT_EQ(0, SetUpAbUpdateCommands(package, zip, status_fd, &cmd));
286     ASSERT_EQ(5U, cmd.size());
287     ASSERT_EQ("/system/bin/update_engine_sideload", cmd[0]);
288     ASSERT_EQ("--payload=file://" + package, cmd[1]);
289     ASSERT_EQ("--offset=" + std::to_string(payload_entry.offset), cmd[2]);
290     ASSERT_EQ("--headers=" + properties, cmd[3]);
291     ASSERT_EQ("--status_fd=" + std::to_string(status_fd), cmd[4]);
292   } else {
293     ASSERT_EQ(INSTALL_ERROR, CheckPackageMetadata(metadata, OtaType::AB));
294   }
295   CloseArchive(zip);
296 }
297 
TEST(InstallTest,SetUpAbUpdateCommands)298 TEST(InstallTest, SetUpAbUpdateCommands) {
299   // Empty serialno will pass the verification.
300   VerifyAbUpdateCommands({});
301 }
302 
TEST(InstallTest,SetUpAbUpdateCommands_MissingPayloadPropertiesTxt)303 TEST(InstallTest, SetUpAbUpdateCommands_MissingPayloadPropertiesTxt) {
304   TemporaryFile temp_file;
305 
306   std::string device = android::base::GetProperty("ro.product.device", "");
307   ASSERT_NE("", device);
308   std::string timestamp = android::base::GetProperty("ro.build.date.utc", "");
309   ASSERT_NE("", timestamp);
310   std::string metadata = android::base::Join(
311       std::vector<std::string>{
312           "ota-type=AB", "pre-device=" + device, "post-timestamp=" + timestamp,
313       },
314       "\n");
315 
316   BuildZipArchive(
317       {
318           { "payload.bin", "" },
319           { "META-INF/com/android/metadata", metadata },
320       },
321       temp_file.release(), kCompressStored);
322 
323   ZipArchiveHandle zip;
324   ASSERT_EQ(0, OpenArchive(temp_file.path, &zip));
325   int status_fd = 10;
326   std::string package = "/path/to/update.zip";
327   std::vector<std::string> cmd;
328   ASSERT_EQ(INSTALL_CORRUPT, SetUpAbUpdateCommands(package, zip, status_fd, &cmd));
329   CloseArchive(zip);
330 }
331 
TEST(InstallTest,SetUpAbUpdateCommands_MultipleSerialnos)332 TEST(InstallTest, SetUpAbUpdateCommands_MultipleSerialnos) {
333   std::string serialno = android::base::GetProperty("ro.serialno", "");
334   ASSERT_NE("", serialno);
335 
336   // Single matching serialno will pass the verification.
337   VerifyAbUpdateCommands(serialno);
338 
339   static constexpr char alphabet[] =
340       "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
341   auto generator = []() { return alphabet[rand() % (sizeof(alphabet) - 1)]; };
342 
343   // Generate 900 random serial numbers.
344   std::string random_serialno;
345   for (size_t i = 0; i < 900; i++) {
346     generate_n(back_inserter(random_serialno), serialno.size(), generator);
347     random_serialno.append("|");
348   }
349   // Random serialnos should fail the verification.
350   VerifyAbUpdateCommands(random_serialno, false);
351 
352   std::string long_serialno = random_serialno + serialno + "|";
353   for (size_t i = 0; i < 99; i++) {
354     generate_n(back_inserter(long_serialno), serialno.size(), generator);
355     long_serialno.append("|");
356   }
357   // String with the matching serialno should pass the verification.
358   VerifyAbUpdateCommands(long_serialno);
359 }
360 
test_check_package_metadata(const std::string & metadata_string,OtaType ota_type,int exptected_result)361 static void test_check_package_metadata(const std::string& metadata_string, OtaType ota_type,
362                                         int exptected_result) {
363   TemporaryFile temp_file;
364   BuildZipArchive(
365       {
366           { "META-INF/com/android/metadata", metadata_string },
367       },
368       temp_file.release(), kCompressStored);
369 
370   ZipArchiveHandle zip;
371   ASSERT_EQ(0, OpenArchive(temp_file.path, &zip));
372 
373   std::map<std::string, std::string> metadata;
374   ASSERT_TRUE(ReadMetadataFromPackage(zip, &metadata));
375   ASSERT_EQ(exptected_result, CheckPackageMetadata(metadata, ota_type));
376   CloseArchive(zip);
377 }
378 
TEST(InstallTest,CheckPackageMetadata_ota_type)379 TEST(InstallTest, CheckPackageMetadata_ota_type) {
380   std::string device = android::base::GetProperty("ro.product.device", "");
381   ASSERT_NE("", device);
382 
383   // ota-type must be present
384   std::string metadata = android::base::Join(
385       std::vector<std::string>{
386           "pre-device=" + device,
387           "post-timestamp=" + std::to_string(std::numeric_limits<int64_t>::max()),
388       },
389       "\n");
390   test_check_package_metadata(metadata, OtaType::AB, INSTALL_ERROR);
391 
392   // Checks if ota-type matches
393   metadata = android::base::Join(
394       std::vector<std::string>{
395           "ota-type=AB",
396           "pre-device=" + device,
397           "post-timestamp=" + std::to_string(std::numeric_limits<int64_t>::max()),
398       },
399       "\n");
400   test_check_package_metadata(metadata, OtaType::AB, 0);
401 
402   test_check_package_metadata(metadata, OtaType::BRICK, INSTALL_ERROR);
403 }
404 
TEST(InstallTest,CheckPackageMetadata_device_type)405 TEST(InstallTest, CheckPackageMetadata_device_type) {
406   // device type can not be empty
407   std::string metadata = android::base::Join(
408       std::vector<std::string>{
409           "ota-type=BRICK",
410       },
411       "\n");
412   test_check_package_metadata(metadata, OtaType::BRICK, INSTALL_ERROR);
413 
414   // device type mismatches
415   metadata = android::base::Join(
416       std::vector<std::string>{
417           "ota-type=BRICK",
418           "pre-device=dummy_device_type",
419       },
420       "\n");
421   test_check_package_metadata(metadata, OtaType::BRICK, INSTALL_ERROR);
422 }
423 
TEST(InstallTest,CheckPackageMetadata_serial_number_smoke)424 TEST(InstallTest, CheckPackageMetadata_serial_number_smoke) {
425   std::string device = android::base::GetProperty("ro.product.device", "");
426   ASSERT_NE("", device);
427 
428   // Serial number doesn't need to exist
429   std::string metadata = android::base::Join(
430       std::vector<std::string>{
431           "ota-type=BRICK",
432           "pre-device=" + device,
433       },
434       "\n");
435   test_check_package_metadata(metadata, OtaType::BRICK, 0);
436 
437   // Serial number mismatches
438   metadata = android::base::Join(
439       std::vector<std::string>{
440           "ota-type=BRICK",
441           "pre-device=" + device,
442           "serialno=dummy_serial",
443       },
444       "\n");
445   test_check_package_metadata(metadata, OtaType::BRICK, INSTALL_ERROR);
446 
447   std::string serialno = android::base::GetProperty("ro.serialno", "");
448   ASSERT_NE("", serialno);
449   metadata = android::base::Join(
450       std::vector<std::string>{
451           "ota-type=BRICK",
452           "pre-device=" + device,
453           "serialno=" + serialno,
454       },
455       "\n");
456   test_check_package_metadata(metadata, OtaType::BRICK, 0);
457 }
458 
TEST(InstallTest,CheckPackageMetadata_multiple_serial_number)459 TEST(InstallTest, CheckPackageMetadata_multiple_serial_number) {
460   std::string device = android::base::GetProperty("ro.product.device", "");
461   ASSERT_NE("", device);
462 
463   std::string serialno = android::base::GetProperty("ro.serialno", "");
464   ASSERT_NE("", serialno);
465 
466   std::vector<std::string> serial_numbers;
467   // Creates a dummy serial number string.
468   for (char c = 'a'; c <= 'z'; c++) {
469     serial_numbers.emplace_back(serialno.size(), c);
470   }
471 
472   // No matched serialno found.
473   std::string metadata = android::base::Join(
474       std::vector<std::string>{
475           "ota-type=BRICK",
476           "pre-device=" + device,
477           "serialno=" + android::base::Join(serial_numbers, '|'),
478       },
479       "\n");
480   test_check_package_metadata(metadata, OtaType::BRICK, INSTALL_ERROR);
481 
482   serial_numbers.emplace_back(serialno);
483   std::shuffle(serial_numbers.begin(), serial_numbers.end(), std::default_random_engine());
484   metadata = android::base::Join(
485       std::vector<std::string>{
486           "ota-type=BRICK",
487           "pre-device=" + device,
488           "serialno=" + android::base::Join(serial_numbers, '|'),
489       },
490       "\n");
491   test_check_package_metadata(metadata, OtaType::BRICK, 0);
492 }
493 
TEST(InstallTest,CheckPackageMetadata_ab_build_version)494 TEST(InstallTest, CheckPackageMetadata_ab_build_version) {
495   std::string device = android::base::GetProperty("ro.product.device", "");
496   ASSERT_NE("", device);
497 
498   std::string build_version = android::base::GetProperty("ro.build.version.incremental", "");
499   ASSERT_NE("", build_version);
500 
501   std::string metadata = android::base::Join(
502       std::vector<std::string>{
503           "ota-type=AB",
504           "pre-device=" + device,
505           "pre-build-incremental=" + build_version,
506           "post-timestamp=" + std::to_string(std::numeric_limits<int64_t>::max()),
507       },
508       "\n");
509   test_check_package_metadata(metadata, OtaType::AB, 0);
510 
511   metadata = android::base::Join(
512       std::vector<std::string>{
513           "ota-type=AB",
514           "pre-device=" + device,
515           "pre-build-incremental=dummy_build",
516           "post-timestamp=" + std::to_string(std::numeric_limits<int64_t>::max()),
517       },
518       "\n");
519   test_check_package_metadata(metadata, OtaType::AB, INSTALL_ERROR);
520 }
521 
TEST(InstallTest,CheckPackageMetadata_ab_fingerprint)522 TEST(InstallTest, CheckPackageMetadata_ab_fingerprint) {
523   std::string device = android::base::GetProperty("ro.product.device", "");
524   ASSERT_NE("", device);
525 
526   std::string finger_print = android::base::GetProperty("ro.build.fingerprint", "");
527   ASSERT_NE("", finger_print);
528 
529   std::string metadata = android::base::Join(
530       std::vector<std::string>{
531           "ota-type=AB",
532           "pre-device=" + device,
533           "pre-build=" + finger_print,
534           "post-timestamp=" + std::to_string(std::numeric_limits<int64_t>::max()),
535       },
536       "\n");
537   test_check_package_metadata(metadata, OtaType::AB, 0);
538 
539   metadata = android::base::Join(
540       std::vector<std::string>{
541           "ota-type=AB",
542           "pre-device=" + device,
543           "pre-build=dummy_build_fingerprint",
544           "post-timestamp=" + std::to_string(std::numeric_limits<int64_t>::max()),
545       },
546       "\n");
547   test_check_package_metadata(metadata, OtaType::AB, INSTALL_ERROR);
548 }
549 
TEST(InstallTest,CheckPackageMetadata_ab_post_timestamp)550 TEST(InstallTest, CheckPackageMetadata_ab_post_timestamp) {
551   std::string device = android::base::GetProperty("ro.product.device", "");
552   ASSERT_NE("", device);
553 
554   // post timestamp is required for upgrade.
555   std::string metadata = android::base::Join(
556       std::vector<std::string>{
557           "ota-type=AB",
558           "pre-device=" + device,
559       },
560       "\n");
561   test_check_package_metadata(metadata, OtaType::AB, INSTALL_ERROR);
562 
563   // post timestamp should be larger than the timestamp on device.
564   metadata = android::base::Join(
565       std::vector<std::string>{
566           "ota-type=AB",
567           "pre-device=" + device,
568           "post-timestamp=0",
569       },
570       "\n");
571   test_check_package_metadata(metadata, OtaType::AB, INSTALL_ERROR);
572 
573   // fingerprint is required for downgrade
574   metadata = android::base::Join(
575       std::vector<std::string>{
576           "ota-type=AB",
577           "pre-device=" + device,
578           "post-timestamp=0",
579           "ota-downgrade=yes",
580       },
581       "\n");
582   test_check_package_metadata(metadata, OtaType::AB, INSTALL_ERROR);
583 
584   std::string finger_print = android::base::GetProperty("ro.build.fingerprint", "");
585   ASSERT_NE("", finger_print);
586 
587   metadata = android::base::Join(
588       std::vector<std::string>{
589           "ota-type=AB",
590           "pre-device=" + device,
591           "post-timestamp=0",
592           "pre-build=" + finger_print,
593           "ota-downgrade=yes",
594       },
595       "\n");
596   test_check_package_metadata(metadata, OtaType::AB, 0);
597 }
598