Home | History | Annotate | Download | only in cmd
      1 /*
      2  * Copyright (C) 2018 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 "Convert.h"
     18 
     19 #include "LoadedApk.h"
     20 #include "test/Test.h"
     21 #include "ziparchive/zip_archive.h"
     22 
     23 using testing::Eq;
     24 using testing::Ne;
     25 
     26 namespace aapt {
     27 
     28 using ConvertTest = CommandTestFixture;
     29 
     30 TEST_F(ConvertTest, RemoveRawXmlStrings) {
     31   StdErrDiagnostics diag;
     32   const std::string compiled_files_dir = GetTestPath("compiled");
     33   ASSERT_TRUE(CompileFile(GetTestPath("res/xml/test.xml"), R"(<Item AgentCode="007"/>)",
     34                           compiled_files_dir, &diag));
     35 
     36   const std::string out_apk = GetTestPath("out.apk");
     37   std::vector<std::string> link_args = {
     38       "--manifest", GetDefaultManifest(),
     39       "-o", out_apk,
     40       "--keep-raw-values",
     41       "--proto-format"
     42   };
     43 
     44   ASSERT_TRUE(Link(link_args, compiled_files_dir, &diag));
     45 
     46   const std::string out_convert_apk = GetTestPath("out_convert.apk");
     47   std::vector<android::StringPiece> convert_args = {
     48       "-o", out_convert_apk,
     49       "--output-format", "binary",
     50       out_apk,
     51   };
     52   ASSERT_THAT(ConvertCommand().Execute(convert_args, &std::cerr), Eq(0));
     53 
     54   // Load the binary xml tree
     55   android::ResXMLTree tree;
     56   std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_convert_apk, &diag);
     57 
     58   std::unique_ptr<io::IData> data = OpenFileAsData(apk.get(), "res/xml/test.xml");
     59   ASSERT_THAT(data, Ne(nullptr));
     60 
     61   AssertLoadXml(apk.get(), data.get(), &tree);
     62 
     63   // Check that the raw string index has not been assigned
     64   EXPECT_THAT(tree.getAttributeValueStringID(0), Eq(-1));
     65 }
     66 
     67 TEST_F(ConvertTest, KeepRawXmlStrings) {
     68   StdErrDiagnostics diag;
     69   const std::string compiled_files_dir = GetTestPath("compiled");
     70   ASSERT_TRUE(CompileFile(GetTestPath("res/xml/test.xml"), R"(<Item AgentCode="007"/>)",
     71                           compiled_files_dir, &diag));
     72 
     73   const std::string out_apk = GetTestPath("out.apk");
     74   std::vector<std::string> link_args = {
     75       "--manifest", GetDefaultManifest(),
     76       "-o", out_apk,
     77       "--keep-raw-values",
     78       "--proto-format"
     79   };
     80 
     81   ASSERT_TRUE(Link(link_args, compiled_files_dir, &diag));
     82 
     83   const std::string out_convert_apk = GetTestPath("out_convert.apk");
     84   std::vector<android::StringPiece> convert_args = {
     85       "-o", out_convert_apk,
     86       "--output-format", "binary",
     87       "--keep-raw-values",
     88       out_apk,
     89   };
     90   ASSERT_THAT(ConvertCommand().Execute(convert_args, &std::cerr), Eq(0));
     91 
     92   // Load the binary xml tree
     93   android::ResXMLTree tree;
     94   std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_convert_apk, &diag);
     95 
     96   std::unique_ptr<io::IData> data = OpenFileAsData(apk.get(), "res/xml/test.xml");
     97   ASSERT_THAT(data, Ne(nullptr));
     98 
     99   AssertLoadXml(apk.get(), data.get(), &tree);
    100 
    101   // Check that the raw string index has been set to the correct string pool entry
    102   int32_t raw_index = tree.getAttributeValueStringID(0);
    103   ASSERT_THAT(raw_index, Ne(-1));
    104   EXPECT_THAT(util::GetString(tree.getStrings(), static_cast<size_t>(raw_index)), Eq("007"));
    105 }
    106 
    107 TEST_F(ConvertTest, DuplicateEntriesWrittenOnce) {
    108   StdErrDiagnostics diag;
    109   const std::string apk_path =
    110       file::BuildPath({android::base::GetExecutableDirectory(),
    111                        "integration-tests", "ConvertTest", "duplicate_entries.apk"});
    112 
    113   const std::string out_convert_apk = GetTestPath("out_convert.apk");
    114   std::vector<android::StringPiece> convert_args = {
    115       "-o", out_convert_apk,
    116       "--output-format", "proto",
    117       apk_path
    118   };
    119   ASSERT_THAT(ConvertCommand().Execute(convert_args, &std::cerr), Eq(0));
    120 
    121   ZipArchiveHandle handle;
    122   ASSERT_THAT(OpenArchive(out_convert_apk.c_str(), &handle), Eq(0));
    123 
    124   void* cookie = nullptr;
    125 
    126   ZipString prefix("res/theme/10");
    127   int32_t result = StartIteration(handle, &cookie, &prefix, nullptr);
    128 
    129   // If this is -5, that means we've found a duplicate entry and this test has failed
    130   EXPECT_THAT(result, Eq(0));
    131 
    132   // But if read succeeds, verify only one res/theme/10 entry
    133   int count = 0;
    134 
    135   // Can't pass nullptrs into Next()
    136   ZipString zip_name;
    137   ZipEntry zip_data;
    138 
    139   while ((result = Next(cookie, &zip_data, &zip_name)) == 0) {
    140     count++;
    141   }
    142 
    143   EndIteration(cookie);
    144 
    145   EXPECT_THAT(count, Eq(1));
    146 }
    147 
    148 }  // namespace aapt