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