1 /*
2 * Copyright (C) 2021 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 <android-base/file.h>
18 #include <gtest/gtest.h>
19 #include <idmap2/FabricatedOverlay.h>
20
21 #include <fstream>
22 #include <utility>
23
24 namespace android::idmap2 {
25
TEST(FabricatedOverlayTests,OverlayInfo)26 TEST(FabricatedOverlayTests, OverlayInfo) {
27 auto overlay =
28 FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
29 .SetOverlayable("TestResources")
30 .Build();
31
32 ASSERT_TRUE(overlay);
33 auto container = FabricatedOverlayContainer::FromOverlay(std::move(*overlay));
34 auto info = container->FindOverlayInfo("SandTheme");
35 ASSERT_TRUE(info);
36 EXPECT_EQ("SandTheme", (*info).name);
37 EXPECT_EQ("TestResources", (*info).target_name);
38
39 info = container->FindOverlayInfo("OceanTheme");
40 ASSERT_FALSE(info);
41 }
42
TEST(FabricatedOverlayTests,SetResourceValue)43 TEST(FabricatedOverlayTests, SetResourceValue) {
44 auto overlay =
45 FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
46 .SetResourceValue("com.example.target:integer/int1", Res_value::TYPE_INT_DEC, 1U)
47 .SetResourceValue("com.example.target.split:integer/int2", Res_value::TYPE_INT_DEC, 2U)
48 .SetResourceValue("string/int3", Res_value::TYPE_REFERENCE, 0x7f010000)
49 .Build();
50 ASSERT_TRUE(overlay);
51 auto container = FabricatedOverlayContainer::FromOverlay(std::move(*overlay));
52 auto info = container->FindOverlayInfo("SandTheme");
53 ASSERT_TRUE(info);
54 ASSERT_TRUE((*info).target_name.empty());
55
56 auto crc = (*container).GetCrc();
57 ASSERT_TRUE(crc) << crc.GetErrorMessage();
58 EXPECT_NE(0U, *crc);
59
60 auto pairs = container->GetOverlayData(*info);
61 ASSERT_TRUE(pairs);
62 EXPECT_FALSE(pairs->string_pool_data.has_value());
63 ASSERT_EQ(3U, pairs->pairs.size());
64
65 auto& it = pairs->pairs[0];
66 ASSERT_EQ("com.example.target:integer/int1", it.resource_name);
67 auto entry = std::get_if<TargetValue>(&it.value);
68 ASSERT_NE(nullptr, entry);
69 ASSERT_EQ(1U, entry->data_value);
70 ASSERT_EQ(Res_value::TYPE_INT_DEC, entry->data_type);
71
72 it = pairs->pairs[1];
73 ASSERT_EQ("com.example.target:string/int3", it.resource_name);
74 entry = std::get_if<TargetValue>(&it.value);
75 ASSERT_NE(nullptr, entry);
76 ASSERT_EQ(0x7f010000, entry->data_value);
77 ASSERT_EQ(Res_value::TYPE_REFERENCE, entry->data_type);
78
79 it = pairs->pairs[2];
80 ASSERT_EQ("com.example.target.split:integer/int2", it.resource_name);
81 entry = std::get_if<TargetValue>(&it.value);
82 ASSERT_NE(nullptr, entry);
83 ASSERT_EQ(2U, entry->data_value);
84 ASSERT_EQ(Res_value::TYPE_INT_DEC, entry->data_type);
85 }
86
TEST(FabricatedOverlayTests,SetResourceValueBadArgs)87 TEST(FabricatedOverlayTests, SetResourceValueBadArgs) {
88 {
89 auto builder =
90 FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
91 .SetResourceValue("int1", Res_value::TYPE_INT_DEC, 1U);
92 ASSERT_FALSE(builder.Build());
93 }
94 {
95 auto builder =
96 FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
97 .SetResourceValue("com.example.target:int2", Res_value::TYPE_INT_DEC, 1U);
98 ASSERT_FALSE(builder.Build());
99 }
100 }
101
TEST(FabricatedOverlayTests,SerializeAndDeserialize)102 TEST(FabricatedOverlayTests, SerializeAndDeserialize) {
103 auto overlay =
104 FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
105 .SetOverlayable("TestResources")
106 .SetResourceValue("com.example.target:integer/int1", Res_value::TYPE_INT_DEC, 1U)
107 .Build();
108 ASSERT_TRUE(overlay);
109 TemporaryFile tf;
110 std::ofstream out(tf.path);
111 ASSERT_TRUE((*overlay).ToBinaryStream(out));
112 out.close();
113
114 auto container = OverlayResourceContainer::FromPath(tf.path);
115 ASSERT_TRUE(container) << container.GetErrorMessage();
116 EXPECT_EQ(tf.path, (*container)->GetPath());
117
118 auto crc = (*container)->GetCrc();
119 ASSERT_TRUE(crc) << crc.GetErrorMessage();
120 EXPECT_NE(0U, *crc);
121
122 auto info = (*container)->FindOverlayInfo("SandTheme");
123 ASSERT_TRUE(info) << info.GetErrorMessage();
124 EXPECT_EQ("SandTheme", (*info).name);
125 EXPECT_EQ("TestResources", (*info).target_name);
126
127 auto pairs = (*container)->GetOverlayData(*info);
128 ASSERT_TRUE(pairs) << pairs.GetErrorMessage();
129 EXPECT_EQ(1U, pairs->pairs.size());
130
131 auto& it = pairs->pairs[0];
132 ASSERT_EQ("com.example.target:integer/int1", it.resource_name);
133 auto entry = std::get_if<TargetValue>(&it.value);
134 ASSERT_NE(nullptr, entry);
135 EXPECT_EQ(1U, entry->data_value);
136 EXPECT_EQ(Res_value::TYPE_INT_DEC, entry->data_type);
137 }
138
139 } // namespace android::idmap2
140