Skip to content

Commit c2127c7

Browse files
Treehugger RobotAndroid (Google) Code Review
authored andcommitted
Merge "GpuService: Add FeatureOverrideParser" into main
2 parents 88c634d + 8e518c0 commit c2127c7

10 files changed

Lines changed: 696 additions & 1 deletion

File tree

services/gpuservice/Android.bp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,16 @@ cc_defaults {
1919
],
2020
}
2121

22+
cc_aconfig_library {
23+
name: "gpuservice_flags_c_lib",
24+
aconfig_declarations: "graphicsenv_flags",
25+
}
26+
2227
cc_defaults {
2328
name: "libgpuservice_defaults",
2429
defaults: [
2530
"gpuservice_defaults",
31+
"libfeatureoverride_deps",
2632
"libgfxstats_deps",
2733
"libgpumem_deps",
2834
"libgpumemtracer_deps",
@@ -40,8 +46,11 @@ cc_defaults {
4046
"libgraphicsenv",
4147
"liblog",
4248
"libutils",
49+
"server_configurable_flags",
4350
],
4451
static_libs: [
52+
"gpuservice_flags_c_lib",
53+
"libfeatureoverride",
4554
"libgfxstats",
4655
"libgpumem",
4756
"libgpumemtracer",
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// Copyright 2024 The Android Open Source Project
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package {
16+
// See: http://go/android-license-faq
17+
// A large-scale-change added 'default_applicable_licenses' to import
18+
// all of the 'license_kinds' from "frameworks_native_license"
19+
// to get the below license kinds:
20+
// SPDX-license-identifier-Apache-2.0
21+
default_applicable_licenses: ["frameworks_native_license"],
22+
}
23+
24+
cc_defaults {
25+
name: "libfeatureoverride_deps",
26+
include_dirs: [
27+
"external/protobuf",
28+
"external/protobuf/src",
29+
],
30+
header_libs: [
31+
"libbase_headers",
32+
],
33+
shared_libs: [
34+
"libbase",
35+
"libgraphicsenv",
36+
"liblog",
37+
],
38+
static_libs: [
39+
"libprotobuf-cpp-lite-ndk",
40+
],
41+
}
42+
43+
filegroup {
44+
name: "feature_config_proto_definitions",
45+
srcs: [
46+
"proto/feature_config.proto",
47+
],
48+
}
49+
50+
genrule {
51+
name: "feature_config_proto_lite_gen_headers",
52+
srcs: [
53+
":feature_config_proto_definitions",
54+
],
55+
tools: [
56+
"aprotoc",
57+
],
58+
cmd: "$(location aprotoc) " +
59+
"--proto_path=frameworks/native/services/gpuservice/feature_override " +
60+
"--cpp_out=lite=true:$(genDir)/frameworks/native/services/gpuservice/feature_override " +
61+
"$(locations :feature_config_proto_definitions)",
62+
out: [
63+
"frameworks/native/services/gpuservice/feature_override/proto/feature_config.pb.h",
64+
],
65+
export_include_dirs: [
66+
"frameworks/native/services/gpuservice/feature_override/proto/",
67+
],
68+
}
69+
70+
cc_library_static {
71+
name: "libfeatureoverride",
72+
defaults: [
73+
"libfeatureoverride_deps",
74+
],
75+
srcs: [
76+
":feature_config_proto_definitions",
77+
"FeatureOverrideParser.cpp",
78+
],
79+
local_include_dirs: [
80+
"include",
81+
],
82+
cflags: [
83+
"-Wall",
84+
"-Werror",
85+
"-Wimplicit-fallthrough",
86+
],
87+
cppflags: [
88+
"-Wno-sign-compare",
89+
],
90+
export_include_dirs: ["include"],
91+
proto: {
92+
type: "lite",
93+
static: true,
94+
},
95+
generated_headers: [
96+
"feature_config_proto_lite_gen_headers",
97+
],
98+
}
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/*
2+
* Copyright 2025 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 <feature_override/FeatureOverrideParser.h>
18+
19+
#include <chrono>
20+
#include <fstream>
21+
#include <sstream>
22+
#include <string>
23+
#include <sys/stat.h>
24+
#include <vector>
25+
26+
#include <graphicsenv/FeatureOverrides.h>
27+
#include <log/log.h>
28+
29+
#include "feature_config.pb.h"
30+
31+
namespace {
32+
33+
void resetFeatureOverrides(android::FeatureOverrides &featureOverrides) {
34+
featureOverrides.mGlobalFeatures.clear();
35+
featureOverrides.mPackageFeatures.clear();
36+
}
37+
38+
void initFeatureConfig(android::FeatureConfig &featureConfig,
39+
const feature_override::FeatureConfig &featureConfigProto) {
40+
featureConfig.mFeatureName = featureConfigProto.feature_name();
41+
featureConfig.mEnabled = featureConfigProto.enabled();
42+
}
43+
44+
feature_override::FeatureOverrideProtos readFeatureConfigProtos(std::string configFilePath) {
45+
feature_override::FeatureOverrideProtos overridesProtos;
46+
47+
std::ifstream protobufBinaryFile(configFilePath.c_str());
48+
if (protobufBinaryFile.fail()) {
49+
ALOGE("Failed to open feature config file: `%s`.", configFilePath.c_str());
50+
return overridesProtos;
51+
}
52+
53+
std::stringstream buffer;
54+
buffer << protobufBinaryFile.rdbuf();
55+
std::string serializedConfig = buffer.str();
56+
std::vector<uint8_t> serialized(
57+
reinterpret_cast<const uint8_t *>(serializedConfig.data()),
58+
reinterpret_cast<const uint8_t *>(serializedConfig.data()) +
59+
serializedConfig.size());
60+
61+
if (!overridesProtos.ParseFromArray(serialized.data(),
62+
static_cast<int>(serialized.size()))) {
63+
ALOGE("Failed to parse GpuConfig protobuf data.");
64+
}
65+
66+
return overridesProtos;
67+
}
68+
69+
} // namespace
70+
71+
namespace android {
72+
73+
std::string FeatureOverrideParser::getFeatureOverrideFilePath() const {
74+
const std::string kConfigFilePath = "/system/etc/angle/feature_config_vk.binarypb";
75+
76+
return kConfigFilePath;
77+
}
78+
79+
bool FeatureOverrideParser::shouldReloadFeatureOverrides() const {
80+
std::string configFilePath = getFeatureOverrideFilePath();
81+
struct stat fileStat{};
82+
if (stat(getFeatureOverrideFilePath().c_str(), &fileStat) != 0) {
83+
ALOGE("Error getting file information for '%s': %s", getFeatureOverrideFilePath().c_str(),
84+
strerror(errno));
85+
// stat'ing the file failed, so return false since reading it will also likely fail.
86+
return false;
87+
}
88+
89+
return fileStat.st_mtime > mLastProtobufReadTime;
90+
}
91+
92+
void FeatureOverrideParser::forceFileRead() {
93+
resetFeatureOverrides(mFeatureOverrides);
94+
mLastProtobufReadTime = 0;
95+
}
96+
97+
void FeatureOverrideParser::parseFeatureOverrides() {
98+
const feature_override::FeatureOverrideProtos overridesProtos = readFeatureConfigProtos(
99+
getFeatureOverrideFilePath());
100+
101+
// Global feature overrides.
102+
for (const auto &featureConfigProto: overridesProtos.global_features()) {
103+
FeatureConfig featureConfig;
104+
initFeatureConfig(featureConfig, featureConfigProto);
105+
106+
mFeatureOverrides.mGlobalFeatures.emplace_back(featureConfig);
107+
}
108+
109+
// App-specific feature overrides.
110+
for (auto const &pkgConfigProto: overridesProtos.package_features()) {
111+
const std::string &packageName = pkgConfigProto.package_name();
112+
113+
if (mFeatureOverrides.mPackageFeatures.count(packageName)) {
114+
ALOGE("Package already has feature overrides! Skipping.");
115+
continue;
116+
}
117+
118+
std::vector<FeatureConfig> featureConfigs;
119+
for (const auto &featureConfigProto: pkgConfigProto.feature_configs()) {
120+
FeatureConfig featureConfig;
121+
initFeatureConfig(featureConfig, featureConfigProto);
122+
123+
featureConfigs.emplace_back(featureConfig);
124+
}
125+
126+
mFeatureOverrides.mPackageFeatures[packageName] = featureConfigs;
127+
}
128+
129+
mLastProtobufReadTime = std::chrono::system_clock::to_time_t(
130+
std::chrono::system_clock::now());
131+
}
132+
133+
FeatureOverrides FeatureOverrideParser::getFeatureOverrides() {
134+
if (shouldReloadFeatureOverrides()) {
135+
parseFeatureOverrides();
136+
}
137+
138+
return mFeatureOverrides;
139+
}
140+
141+
} // namespace android
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2024 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+
#ifndef FEATURE_OVERRIDE_PARSER_H_
18+
#define FEATURE_OVERRIDE_PARSER_H_
19+
20+
#include <ctime>
21+
#include <string>
22+
#include <vector>
23+
24+
#include <graphicsenv/FeatureOverrides.h>
25+
26+
namespace android {
27+
28+
class FeatureOverrideParser {
29+
public:
30+
FeatureOverrideParser() = default;
31+
FeatureOverrideParser(const FeatureOverrideParser &) = default;
32+
virtual ~FeatureOverrideParser() = default;
33+
34+
FeatureOverrides getFeatureOverrides();
35+
void forceFileRead();
36+
37+
private:
38+
bool shouldReloadFeatureOverrides() const;
39+
void parseFeatureOverrides();
40+
// Allow FeatureOverrideParserMock to override with the unit test file's path.
41+
virtual std::string getFeatureOverrideFilePath() const;
42+
43+
std::time_t mLastProtobufReadTime = 0;
44+
FeatureOverrides mFeatureOverrides;
45+
};
46+
47+
} // namespace android
48+
49+
#endif // FEATURE_OVERRIDE_PARSER_H_
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright 2024 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+
syntax = "proto3";
18+
19+
package feature_override;
20+
21+
option optimize_for = LITE_RUNTIME;
22+
23+
/**
24+
* Feature Configuration
25+
* feature_name: Feature name (see external/angle/include/platform/autogen/FeaturesVk_autogen.h).
26+
* enabled: Either enable or disable the feature.
27+
*/
28+
message FeatureConfig
29+
{
30+
string feature_name = 1;
31+
bool enabled = 2;
32+
}
33+
34+
/**
35+
* Package Configuration
36+
* feature_configs: List of features configs for the package.
37+
*/
38+
message PackageConfig
39+
{
40+
string package_name = 1;
41+
repeated FeatureConfig feature_configs = 2;
42+
}
43+
44+
/**
45+
* Feature Overrides
46+
* global_features: Features to apply globally, for every package.
47+
* package_features: Features to apply for individual packages.
48+
*/
49+
message FeatureOverrideProtos
50+
{
51+
repeated FeatureConfig global_features = 1;
52+
repeated PackageConfig package_features = 2;
53+
}

services/gpuservice/include/gpuservice/GpuService.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include <binder/IInterface.h>
2121
#include <cutils/compiler.h>
22+
#include <feature_override/FeatureOverrideParser.h>
2223
#include <graphicsenv/GpuStatsInfo.h>
2324
#include <graphicsenv/IGpuService.h>
2425
#include <serviceutils/PriorityDumper.h>
@@ -96,6 +97,7 @@ class GpuService : public BnGpuService, public PriorityDumper {
9697
std::string mDeveloperDriverPath;
9798
std::unique_ptr<std::thread> mGpuMemAsyncInitThread;
9899
std::unique_ptr<std::thread> mGpuWorkAsyncInitThread;
100+
FeatureOverrideParser mFeatureOverrideParser;
99101
};
100102

101103
} // namespace android

0 commit comments

Comments
 (0)