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 auto value = assetmanager.GetResource(basic::R::layout::layoutt);
112 if (!value.has_value()) {
113 state.SkipWithError("failed to find R.layout.layout");
114 return;
115 }
116
117 auto layout_path = assetmanager.GetStringPoolForCookie(value->cookie)->string8At(value->data);
118 if (!layout_path.has_value()) {
119 state.SkipWithError("failed to lookup layout path");
120 return;
121 }
122
123 std::unique_ptr<Asset> asset = assetmanager.OpenNonAsset(layout_path->to_string(), value->cookie,
124 Asset::ACCESS_BUFFER);
125 if (asset == nullptr) {
126 state.SkipWithError("failed to load layout");
127 return;
128 }
129
130 ResXMLTree xml_tree;
131 if (xml_tree.setTo(asset->getBuffer(true), asset->getLength(), false /*copyData*/) != NO_ERROR) {
132 state.SkipWithError("corrupt xml layout");
133 return;
134 }
135
136 // Skip to the first tag.
137 while (xml_tree.next() != ResXMLParser::START_TAG) {
138 }
139
140 std::unique_ptr<Theme> theme = assetmanager.NewTheme();
141 theme->ApplyStyle(Theme_Material_Light);
142
143 std::array<uint32_t, 92> attrs{
144 {0x0101000e, 0x01010034, 0x01010095, 0x01010096, 0x01010097, 0x01010098, 0x01010099,
145 0x0101009a, 0x0101009b, 0x010100ab, 0x010100af, 0x010100b0, 0x010100b1, 0x0101011f,
146 0x01010120, 0x0101013f, 0x01010140, 0x0101014e, 0x0101014f, 0x01010150, 0x01010151,
147 0x01010152, 0x01010153, 0x01010154, 0x01010155, 0x01010156, 0x01010157, 0x01010158,
148 0x01010159, 0x0101015a, 0x0101015b, 0x0101015c, 0x0101015d, 0x0101015e, 0x0101015f,
149 0x01010160, 0x01010161, 0x01010162, 0x01010163, 0x01010164, 0x01010165, 0x01010166,
150 0x01010167, 0x01010168, 0x01010169, 0x0101016a, 0x0101016b, 0x0101016c, 0x0101016d,
151 0x0101016e, 0x0101016f, 0x01010170, 0x01010171, 0x01010217, 0x01010218, 0x0101021d,
152 0x01010220, 0x01010223, 0x01010224, 0x01010264, 0x01010265, 0x01010266, 0x010102c5,
153 0x010102c6, 0x010102c7, 0x01010314, 0x01010315, 0x01010316, 0x0101035e, 0x0101035f,
154 0x01010362, 0x01010374, 0x0101038c, 0x01010392, 0x01010393, 0x010103ac, 0x0101045d,
155 0x010104b6, 0x010104b7, 0x010104d6, 0x010104d7, 0x010104dd, 0x010104de, 0x010104df,
156 0x01010535, 0x01010536, 0x01010537, 0x01010538, 0x01010546, 0x01010567, 0x011100c9,
157 0x011100ca}};
158
159 std::array<uint32_t, attrs.size() * STYLE_NUM_ENTRIES> values;
160 std::array<uint32_t, attrs.size() + 1> indices;
161 while (state.KeepRunning()) {
162 ApplyStyle(theme.get(), &xml_tree, 0x01010084u /*def_style_attr*/, 0u /*def_style_res*/,
163 attrs.data(), attrs.size(), values.data(), indices.data());
164 }
165 }
166 BENCHMARK(BM_ApplyStyleFramework);
167
168 } // namespace android
169