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 "benchmark/benchmark.h"
18
19 //#include "android-base/stringprintf.h"
20 #include "androidfw/ApkAssets.h"
21 #include "androidfw/AssetManager.h"
22 #include "androidfw/AssetManager2.h"
23 #include "androidfw/AttributeResolution.h"
24 #include "androidfw/ResourceTypes.h"
25
26 #include "BenchmarkHelpers.h"
27 #include "data/basic/R.h"
28 #include "data/styles/R.h"
29
30 namespace app = com::android::app;
31 namespace basic = com::android::basic;
32
33 namespace android {
34
35 constexpr const static char* kFrameworkPath = "/system/framework/framework-res.apk";
36 constexpr const static uint32_t Theme_Material_Light = 0x01030237u;
37
BM_ApplyStyle(benchmark::State & state)38 static void BM_ApplyStyle(benchmark::State& state) {
39 std::unique_ptr<const ApkAssets> styles_apk =
40 ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk");
41 if (styles_apk == nullptr) {
42 state.SkipWithError("failed to load assets");
43 return;
44 }
45
46 AssetManager2 assetmanager;
47 assetmanager.SetApkAssets({styles_apk.get()});
48
49 std::unique_ptr<Asset> asset =
50 assetmanager.OpenNonAsset("res/layout/layout.xml", Asset::ACCESS_BUFFER);
51 if (asset == nullptr) {
52 state.SkipWithError("failed to load layout");
53 return;
54 }
55
56 ResXMLTree xml_tree;
57 if (xml_tree.setTo(asset->getBuffer(true), asset->getLength(), false /*copyData*/) != NO_ERROR) {
58 state.SkipWithError("corrupt xml layout");
59 return;
60 }
61
62 // Skip to the first tag.
63 while (xml_tree.next() != ResXMLParser::START_TAG) {
64 }
65
66 std::unique_ptr<Theme> theme = assetmanager.NewTheme();
67 theme->ApplyStyle(app::R::style::StyleTwo);
68
69 std::array<uint32_t, 6> attrs{{app::R::attr::attr_one, app::R::attr::attr_two,
70 app::R::attr::attr_three, app::R::attr::attr_four,
71 app::R::attr::attr_five, app::R::attr::attr_empty}};
72 std::array<uint32_t, attrs.size() * STYLE_NUM_ENTRIES> values;
73 std::array<uint32_t, attrs.size() + 1> indices;
74
75 while (state.KeepRunning()) {
76 ApplyStyle(theme.get(), &xml_tree, 0u /*def_style_attr*/, 0u /*def_style_res*/, attrs.data(),
77 attrs.size(), values.data(), indices.data());
78 }
79 }
80 BENCHMARK(BM_ApplyStyle);
81
BM_ApplyStyleFramework(benchmark::State & state)82 static void BM_ApplyStyleFramework(benchmark::State& state) {
83 std::unique_ptr<const ApkAssets> framework_apk = ApkAssets::Load(kFrameworkPath);
84 if (framework_apk == nullptr) {
85 state.SkipWithError("failed to load framework assets");
86 return;
87 }
88
89 std::unique_ptr<const ApkAssets> basic_apk =
90 ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk");
91 if (basic_apk == nullptr) {
92 state.SkipWithError("failed to load assets");
93 return;
94 }
95
96 AssetManager2 assetmanager;
97 assetmanager.SetApkAssets({framework_apk.get(), basic_apk.get()});
98
99 ResTable_config device_config;
100 memset(&device_config, 0, sizeof(device_config));
101 device_config.language[0] = 'e';
102 device_config.language[1] = 'n';
103 device_config.country[0] = 'U';
104 device_config.country[1] = 'S';
105 device_config.orientation = ResTable_config::ORIENTATION_PORT;
106 device_config.smallestScreenWidthDp = 700;
107 device_config.screenWidthDp = 700;
108 device_config.screenHeightDp = 1024;
109 device_config.sdkVersion = 27;
110
111 Res_value value;
112 ResTable_config config;
113 uint32_t flags = 0u;
114 ApkAssetsCookie cookie =
115 assetmanager.GetResource(basic::R::layout::layoutt, false /*may_be_bag*/,
116 0u /*density_override*/, &value, &config, &flags);
117 if (cookie == kInvalidCookie) {
118 state.SkipWithError("failed to find R.layout.layout");
119 return;
120 }
121
122 size_t len = 0u;
123 const char* layout_path =
124 assetmanager.GetStringPoolForCookie(cookie)->string8At(value.data, &len);
125 if (layout_path == nullptr || len == 0u) {
126 state.SkipWithError("failed to lookup layout path");
127 return;
128 }
129
130 std::unique_ptr<Asset> asset = assetmanager.OpenNonAsset(
131 StringPiece(layout_path, len).to_string(), cookie, Asset::ACCESS_BUFFER);
132 if (asset == nullptr) {
133 state.SkipWithError("failed to load layout");
134 return;
135 }
136
137 ResXMLTree xml_tree;
138 if (xml_tree.setTo(asset->getBuffer(true), asset->getLength(), false /*copyData*/) != NO_ERROR) {
139 state.SkipWithError("corrupt xml layout");
140 return;
141 }
142
143 // Skip to the first tag.
144 while (xml_tree.next() != ResXMLParser::START_TAG) {
145 }
146
147 std::unique_ptr<Theme> theme = assetmanager.NewTheme();
148 theme->ApplyStyle(Theme_Material_Light);
149
150 std::array<uint32_t, 92> attrs{
151 {0x0101000e, 0x01010034, 0x01010095, 0x01010096, 0x01010097, 0x01010098, 0x01010099,
152 0x0101009a, 0x0101009b, 0x010100ab, 0x010100af, 0x010100b0, 0x010100b1, 0x0101011f,
153 0x01010120, 0x0101013f, 0x01010140, 0x0101014e, 0x0101014f, 0x01010150, 0x01010151,
154 0x01010152, 0x01010153, 0x01010154, 0x01010155, 0x01010156, 0x01010157, 0x01010158,
155 0x01010159, 0x0101015a, 0x0101015b, 0x0101015c, 0x0101015d, 0x0101015e, 0x0101015f,
156 0x01010160, 0x01010161, 0x01010162, 0x01010163, 0x01010164, 0x01010165, 0x01010166,
157 0x01010167, 0x01010168, 0x01010169, 0x0101016a, 0x0101016b, 0x0101016c, 0x0101016d,
158 0x0101016e, 0x0101016f, 0x01010170, 0x01010171, 0x01010217, 0x01010218, 0x0101021d,
159 0x01010220, 0x01010223, 0x01010224, 0x01010264, 0x01010265, 0x01010266, 0x010102c5,
160 0x010102c6, 0x010102c7, 0x01010314, 0x01010315, 0x01010316, 0x0101035e, 0x0101035f,
161 0x01010362, 0x01010374, 0x0101038c, 0x01010392, 0x01010393, 0x010103ac, 0x0101045d,
162 0x010104b6, 0x010104b7, 0x010104d6, 0x010104d7, 0x010104dd, 0x010104de, 0x010104df,
163 0x01010535, 0x01010536, 0x01010537, 0x01010538, 0x01010546, 0x01010567, 0x011100c9,
164 0x011100ca}};
165
166 std::array<uint32_t, attrs.size() * STYLE_NUM_ENTRIES> values;
167 std::array<uint32_t, attrs.size() + 1> indices;
168 while (state.KeepRunning()) {
169 ApplyStyle(theme.get(), &xml_tree, 0x01010084u /*def_style_attr*/, 0u /*def_style_res*/,
170 attrs.data(), attrs.size(), values.data(), indices.data());
171 }
172 }
173 BENCHMARK(BM_ApplyStyleFramework);
174
175 } // namespace android
176