Home | History | Annotate | Download | only in cmd
      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 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 "Util.h"
     18 
     19 #include "android-base/stringprintf.h"
     20 
     21 #include "AppInfo.h"
     22 #include "split/TableSplitter.h"
     23 #include "test/Builders.h"
     24 #include "test/Test.h"
     25 #include "util/Files.h"
     26 
     27 using ::android::ConfigDescription;
     28 
     29 namespace aapt {
     30 
     31 #ifdef _WIN32
     32 #define CREATE_PATH(path) android::base::StringPrintf(";%s", path)
     33 #else
     34 #define CREATE_PATH(path) android::base::StringPrintf(":%s", path)
     35 #endif
     36 
     37 #define EXPECT_CONFIG_EQ(constraints, config) \
     38     EXPECT_EQ(constraints.configs.size(), 1); \
     39     EXPECT_EQ(*constraints.configs.begin(), config); \
     40     constraints.configs.clear();
     41 
     42 TEST(UtilTest, SplitNamesAreSanitized) {
     43     AppInfo app_info{"com.pkg"};
     44     SplitConstraints split_constraints{
     45         {test::ParseConfigOrDie("en-rUS-land"), test::ParseConfigOrDie("b+sr+Latn")}};
     46 
     47     const auto doc = GenerateSplitManifest(app_info, split_constraints);
     48     const auto &root = doc->root;
     49     EXPECT_EQ(root->name, "manifest");
     50     // split names cannot contain hyphens or plus signs.
     51     EXPECT_EQ(root->FindAttribute("", "split")->value, "config.b_sr_Latn_en_rUS_land");
     52     // but we should use resource qualifiers verbatim in 'targetConfig'.
     53     EXPECT_EQ(root->FindAttribute("", "targetConfig")->value, "b+sr+Latn,en-rUS-land");
     54 }
     55 
     56 TEST (UtilTest, LongVersionCodeDefined) {
     57   auto doc = test::BuildXmlDom(R"(
     58       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     59         package="com.android.aapt.test" android:versionCode="0x1" android:versionCodeMajor="0x1">
     60       </manifest>)");
     61   SetLongVersionCode(doc->root.get(), 42);
     62 
     63   auto version_code = doc->root->FindAttribute(xml::kSchemaAndroid, "versionCode");
     64   ASSERT_NE(version_code, nullptr);
     65   EXPECT_EQ(version_code->value, "0x0000002a");
     66 
     67   ASSERT_NE(version_code->compiled_value, nullptr);
     68   auto compiled_version_code = ValueCast<BinaryPrimitive>(version_code->compiled_value.get());
     69   ASSERT_NE(compiled_version_code, nullptr);
     70   EXPECT_EQ(compiled_version_code->value.data, 42U);
     71 
     72   auto version_code_major = doc->root->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor");
     73   EXPECT_EQ(version_code_major, nullptr);
     74 }
     75 
     76 TEST (UtilTest, LongVersionCodeUndefined) {
     77   auto doc = test::BuildXmlDom(R"(
     78         <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     79           package="com.android.aapt.test">
     80         </manifest>)");
     81   SetLongVersionCode(doc->root.get(), 420000000000);
     82 
     83   auto version_code = doc->root->FindAttribute(xml::kSchemaAndroid, "versionCode");
     84   ASSERT_NE(version_code, nullptr);
     85   EXPECT_EQ(version_code->value, "0xc9f36800");
     86 
     87   ASSERT_NE(version_code->compiled_value, nullptr);
     88   auto compiled_version_code = ValueCast<BinaryPrimitive>(version_code->compiled_value.get());
     89   ASSERT_NE(compiled_version_code, nullptr);
     90   EXPECT_EQ(compiled_version_code->value.data, 0xc9f36800);
     91 
     92   auto version_code_major = doc->root->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor");
     93   ASSERT_NE(version_code_major, nullptr);
     94   EXPECT_EQ(version_code_major->value, "0x00000061");
     95 
     96   ASSERT_NE(version_code_major->compiled_value, nullptr);
     97   auto compiled_version_code_major = ValueCast<BinaryPrimitive>(
     98       version_code_major->compiled_value.get());
     99   ASSERT_NE(compiled_version_code_major, nullptr);
    100   EXPECT_EQ(compiled_version_code_major->value.data, 0x61);
    101 }
    102 
    103 
    104 TEST (UtilTest, ParseSplitParameters) {
    105   IDiagnostics* diagnostics = test::ContextBuilder().Build().get()->GetDiagnostics();
    106   std::string path;
    107   SplitConstraints constraints;
    108   ConfigDescription expected_configuration;
    109 
    110   // ========== Test IMSI ==========
    111   // mcc: 'mcc[0-9]{3}'
    112   // mnc: 'mnc[0-9]{1,3}'
    113   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("mcc310"),
    114                                   diagnostics, &path, &constraints));
    115   expected_configuration = test::ConfigDescriptionBuilder()
    116       .setMcc(0x0136)
    117       .Build();
    118   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    119 
    120   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("mcc310-mnc004"),
    121                                   diagnostics, &path, &constraints));
    122   expected_configuration = test::ConfigDescriptionBuilder()
    123       .setMcc(0x0136)
    124       .setMnc(0x0004)
    125       .Build();
    126   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    127 
    128   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("mcc310-mnc000"),
    129                                   diagnostics, &path, &constraints));
    130   expected_configuration = test::ConfigDescriptionBuilder()
    131       .setMcc(0x0136)
    132       .setMnc(0xFFFF)
    133       .Build();
    134   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    135 
    136   // ========== Test LOCALE ==========
    137   // locale: '[a-z]{2,3}(-r[a-z]{2})?'
    138   // locale: 'b+[a-z]{2,3}(+[a-z[0-9]]{2})?'
    139   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("es"),
    140                                   diagnostics, &path, &constraints));
    141   expected_configuration = test::ConfigDescriptionBuilder()
    142       .setLanguage(0x6573)
    143       .Build();
    144   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    145 
    146   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("fr-rCA"),
    147                                   diagnostics, &path, &constraints));
    148   expected_configuration = test::ConfigDescriptionBuilder()
    149       .setLanguage(0x6672)
    150       .setCountry(0x4341)
    151       .Build();
    152   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    153 
    154   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("b+es+419"),
    155                                   diagnostics, &path, &constraints));
    156   expected_configuration = test::ConfigDescriptionBuilder()
    157       .setLanguage(0x6573)
    158       .setCountry(0xA424)
    159       .Build();
    160   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    161 
    162   // ========== Test SCREEN_TYPE ==========
    163   // orientation: '(port|land|square)'
    164   // touchscreen: '(notouch|stylus|finger)'
    165   // density" '(anydpi|nodpi|ldpi|mdpi|tvdpi|hdpi|xhdpi|xxhdpi|xxxhdpi|[0-9]*dpi)'
    166   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("square"),
    167                                   diagnostics, &path, &constraints));
    168   expected_configuration = test::ConfigDescriptionBuilder()
    169       .setOrientation(0x03)
    170       .Build();
    171   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    172 
    173   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("stylus"),
    174                                   diagnostics, &path, &constraints));
    175   expected_configuration = test::ConfigDescriptionBuilder()
    176       .setTouchscreen(0x02)
    177       .Build();
    178   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    179 
    180   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("xxxhdpi"),
    181                                   diagnostics, &path, &constraints));
    182   expected_configuration = test::ConfigDescriptionBuilder()
    183       .setDensity(0x0280)
    184       .setSdkVersion(0x0004) // version [any density requires donut]
    185       .Build();
    186   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    187 
    188   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("land-xhdpi-finger"),
    189                                   diagnostics, &path, &constraints));
    190   expected_configuration = test::ConfigDescriptionBuilder()
    191       .setOrientation(0x02)
    192       .setTouchscreen(0x03)
    193       .setDensity(0x0140)
    194       .setSdkVersion(0x0004) // version [any density requires donut]
    195       .Build();
    196   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    197 
    198   // ========== Test INPUT ==========
    199   // keyboard: '(nokeys|qwerty|12key)'
    200   // navigation: '(nonav|dpad|trackball|wheel)'
    201   // inputFlags: '(keysexposed|keyshidden|keyssoft)'
    202   // inputFlags: '(navexposed|navhidden)'
    203   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("qwerty"),
    204                                   diagnostics, &path, &constraints));
    205   expected_configuration = test::ConfigDescriptionBuilder()
    206       .setKeyboard(0x02)
    207       .Build();
    208   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    209 
    210   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("dpad"),
    211                                   diagnostics, &path, &constraints));
    212   expected_configuration = test::ConfigDescriptionBuilder()
    213       .setNavigation(0x02)
    214       .Build();
    215   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    216 
    217   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("keyssoft-navhidden"),
    218                                   diagnostics, &path, &constraints));
    219   expected_configuration = test::ConfigDescriptionBuilder()
    220       .setInputFlags(0x0B)
    221       .Build();
    222   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    223 
    224   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("keyshidden-nokeys-navexposed-trackball"),
    225                                   diagnostics, &path, &constraints));
    226   expected_configuration = test::ConfigDescriptionBuilder()
    227       .setKeyboard(0x01)
    228       .setNavigation(0x03)
    229       .setInputFlags(0x06)
    230       .Build();
    231   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    232 
    233   // ========== Test SCREEN_SIZE ==========
    234   // screenWidth/screenHeight: '[0-9]+x[0-9]+'
    235   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("1920x1080"),
    236                                   diagnostics, &path, &constraints));
    237   expected_configuration = test::ConfigDescriptionBuilder()
    238       .setScreenWidth(0x0780)
    239       .setScreenHeight(0x0438)
    240       .Build();
    241   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    242 
    243   // ========== Test VERSION ==========
    244   // version 'v[0-9]+'
    245 
    246   // ========== Test SCREEN_CONFIG ==========
    247   // screenLayout [direction]: '(ldltr|ldrtl)'
    248   // screenLayout [size]: '(small|normal|large|xlarge)'
    249   // screenLayout [long]: '(long|notlong)'
    250   // uiMode [type]: '(desk|car|television|appliance|watch|vrheadset)'
    251   // uiMode [night]: '(night|notnight)'
    252   // smallestScreenWidthDp: 'sw[0-9]dp'
    253   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("ldrtl"),
    254                                   diagnostics, &path, &constraints));
    255   expected_configuration = test::ConfigDescriptionBuilder()
    256       .setScreenLayout(0x80)
    257       .Build();
    258   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    259 
    260   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("small"),
    261                                   diagnostics, &path, &constraints));
    262   expected_configuration = test::ConfigDescriptionBuilder()
    263       .setScreenLayout(0x01)
    264       .setSdkVersion(0x0004) // screenLayout (size) requires donut
    265       .Build();
    266   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    267 
    268   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("notlong"),
    269                                   diagnostics, &path, &constraints));
    270   expected_configuration = test::ConfigDescriptionBuilder()
    271       .setScreenLayout(0x10)
    272       .setSdkVersion(0x0004) // screenLayout (long) requires donut
    273       .Build();
    274   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    275 
    276   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("ldltr-normal-long"),
    277                                       diagnostics, &path, &constraints));
    278   expected_configuration = test::ConfigDescriptionBuilder()
    279       .setScreenLayout(0x62)
    280       .setSdkVersion(0x0004) // screenLayout (size|long) requires donut
    281       .Build();
    282   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    283 
    284   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("car"),
    285                                   diagnostics, &path, &constraints));
    286   expected_configuration = test::ConfigDescriptionBuilder()
    287       .setUiMode(0x03)
    288       .setSdkVersion(0x0008) // uiMode requires froyo
    289       .Build();
    290   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    291 
    292   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("vrheadset"),
    293                                   diagnostics, &path, &constraints));
    294   expected_configuration = test::ConfigDescriptionBuilder()
    295       .setUiMode(0x07)
    296       .setSdkVersion(0x001A) // uiMode 'vrheadset' requires oreo
    297       .Build();
    298   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    299 
    300   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("television-night"),
    301                                   diagnostics, &path, &constraints));
    302   expected_configuration = test::ConfigDescriptionBuilder()
    303       .setUiMode(0x24)
    304       .setSdkVersion(0x0008) // uiMode requires froyo
    305       .Build();
    306   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    307 
    308   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("sw1920dp"),
    309                                   diagnostics, &path, &constraints));
    310   expected_configuration = test::ConfigDescriptionBuilder()
    311       .setSmallestScreenWidthDp(0x0780)
    312       .setSdkVersion(0x000D) // smallestScreenWidthDp requires honeycomb mr2
    313       .Build();
    314   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    315 
    316   // ========== Test SCREEN_SIZE_DP ==========
    317   // screenWidthDp: 'w[0-9]dp'
    318   // screenHeightDp: 'h[0-9]dp'
    319   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("w1920dp"),
    320                                   diagnostics, &path, &constraints));
    321   expected_configuration = test::ConfigDescriptionBuilder()
    322       .setScreenWidthDp(0x0780)
    323       .setSdkVersion(0x000D) // screenWidthDp requires honeycomb mr2
    324       .Build();
    325   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    326 
    327   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("h1080dp"),
    328                                   diagnostics, &path, &constraints));
    329   expected_configuration = test::ConfigDescriptionBuilder()
    330       .setScreenHeightDp(0x0438)
    331       .setSdkVersion(0x000D) // screenHeightDp requires honeycomb mr2
    332       .Build();
    333   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    334 
    335   // ========== Test SCREEN_CONFIG_2 ==========
    336   // screenLayout2: '(round|notround)'
    337   // colorMode: '(widecg|nowidecg)'
    338   // colorMode: '(highhdr|lowdr)'
    339   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("round"),
    340                                   diagnostics, &path, &constraints));
    341   expected_configuration = test::ConfigDescriptionBuilder()
    342       .setScreenLayout2(0x02)
    343       .setSdkVersion(0x0017) // screenLayout2 (round) requires marshmallow
    344       .Build();
    345   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    346 
    347   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("widecg-highdr"),
    348                                   diagnostics, &path, &constraints));
    349   expected_configuration = test::ConfigDescriptionBuilder()
    350       .setColorMode(0x0A)
    351       .setSdkVersion(0x001A) // colorMode (hdr|colour gamut) requires oreo
    352       .Build();
    353   EXPECT_CONFIG_EQ(constraints, expected_configuration);
    354 }
    355 
    356 TEST (UtilTest, AdjustSplitConstraintsForMinSdk) {
    357   std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
    358 
    359   IDiagnostics* diagnostics = context.get()->GetDiagnostics();
    360   std::vector<SplitConstraints> test_constraints;
    361   std::string path;
    362 
    363   test_constraints.push_back({});
    364   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("v7"),
    365                                   diagnostics, &path, &test_constraints.back()));
    366   test_constraints.push_back({});
    367   ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("xhdpi"),
    368                                   diagnostics, &path, &test_constraints.back()));
    369   EXPECT_EQ(test_constraints.size(), 2);
    370   EXPECT_EQ(test_constraints[0].name, "v7");
    371   EXPECT_EQ(test_constraints[0].configs.size(), 1);
    372   EXPECT_NE(*test_constraints[0].configs.begin(), ConfigDescription::DefaultConfig());
    373   EXPECT_EQ(test_constraints[1].name, "xhdpi");
    374   EXPECT_EQ(test_constraints[1].configs.size(), 1);
    375   EXPECT_NE(*test_constraints[0].configs.begin(), ConfigDescription::DefaultConfig());
    376 
    377   auto adjusted_contraints = AdjustSplitConstraintsForMinSdk(26, test_constraints);
    378   EXPECT_EQ(adjusted_contraints.size(), 2);
    379   EXPECT_EQ(adjusted_contraints[0].name, "v7");
    380   EXPECT_EQ(adjusted_contraints[0].configs.size(), 0);
    381   EXPECT_EQ(adjusted_contraints[1].name, "xhdpi");
    382   EXPECT_EQ(adjusted_contraints[1].configs.size(), 1);
    383   EXPECT_NE(*adjusted_contraints[1].configs.begin(), ConfigDescription::DefaultConfig());
    384 }
    385 
    386 TEST(UtilTest, RegularExperssions) {
    387   std::string valid(".bc$");
    388   std::regex expression = GetRegularExpression(valid);
    389   EXPECT_TRUE(std::regex_search("file.abc", expression));
    390   EXPECT_TRUE(std::regex_search("file.123bc", expression));
    391   EXPECT_FALSE(std::regex_search("abc.zip", expression));
    392 }
    393 
    394 }  // namespace aapt
    395