Loading services/gpuservice/Android.bp +9 −0 Original line number Diff line number Diff line Loading @@ -19,10 +19,16 @@ cc_defaults { ], } cc_aconfig_library { name: "gpuservice_flags_c_lib", aconfig_declarations: "graphicsenv_flags", } cc_defaults { name: "libgpuservice_defaults", defaults: [ "gpuservice_defaults", "libfeatureoverride_deps", "libgfxstats_deps", "libgpumem_deps", "libgpumemtracer_deps", Loading @@ -40,8 +46,11 @@ cc_defaults { "libgraphicsenv", "liblog", "libutils", "server_configurable_flags", ], static_libs: [ "gpuservice_flags_c_lib", "libfeatureoverride", "libgfxstats", "libgpumem", "libgpumemtracer", Loading services/gpuservice/feature_override/Android.bp 0 → 100644 +98 −0 Original line number Diff line number Diff line // Copyright 2024 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package { // See: http://go/android-license-faq // A large-scale-change added 'default_applicable_licenses' to import // all of the 'license_kinds' from "frameworks_native_license" // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_native_license"], } cc_defaults { name: "libfeatureoverride_deps", include_dirs: [ "external/protobuf", "external/protobuf/src", ], header_libs: [ "libbase_headers", ], shared_libs: [ "libbase", "libgraphicsenv", "liblog", ], static_libs: [ "libprotobuf-cpp-lite-ndk", ], } filegroup { name: "feature_config_proto_definitions", srcs: [ "proto/feature_config.proto", ], } genrule { name: "feature_config_proto_lite_gen_headers", srcs: [ ":feature_config_proto_definitions", ], tools: [ "aprotoc", ], cmd: "$(location aprotoc) " + "--proto_path=frameworks/native/services/gpuservice/feature_override " + "--cpp_out=lite=true:$(genDir)/frameworks/native/services/gpuservice/feature_override " + "$(locations :feature_config_proto_definitions)", out: [ "frameworks/native/services/gpuservice/feature_override/proto/feature_config.pb.h", ], export_include_dirs: [ "frameworks/native/services/gpuservice/feature_override/proto/", ], } cc_library_static { name: "libfeatureoverride", defaults: [ "libfeatureoverride_deps", ], srcs: [ ":feature_config_proto_definitions", "FeatureOverrideParser.cpp", ], local_include_dirs: [ "include", ], cflags: [ "-Wall", "-Werror", "-Wimplicit-fallthrough", ], cppflags: [ "-Wno-sign-compare", ], export_include_dirs: ["include"], proto: { type: "lite", static: true, }, generated_headers: [ "feature_config_proto_lite_gen_headers", ], } services/gpuservice/feature_override/FeatureOverrideParser.cpp 0 → 100644 +141 −0 Original line number Diff line number Diff line /* * Copyright 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <feature_override/FeatureOverrideParser.h> #include <chrono> #include <fstream> #include <sstream> #include <string> #include <sys/stat.h> #include <vector> #include <graphicsenv/FeatureOverrides.h> #include <log/log.h> #include "feature_config.pb.h" namespace { void resetFeatureOverrides(android::FeatureOverrides &featureOverrides) { featureOverrides.mGlobalFeatures.clear(); featureOverrides.mPackageFeatures.clear(); } void initFeatureConfig(android::FeatureConfig &featureConfig, const feature_override::FeatureConfig &featureConfigProto) { featureConfig.mFeatureName = featureConfigProto.feature_name(); featureConfig.mEnabled = featureConfigProto.enabled(); } feature_override::FeatureOverrideProtos readFeatureConfigProtos(std::string configFilePath) { feature_override::FeatureOverrideProtos overridesProtos; std::ifstream protobufBinaryFile(configFilePath.c_str()); if (protobufBinaryFile.fail()) { ALOGE("Failed to open feature config file: `%s`.", configFilePath.c_str()); return overridesProtos; } std::stringstream buffer; buffer << protobufBinaryFile.rdbuf(); std::string serializedConfig = buffer.str(); std::vector<uint8_t> serialized( reinterpret_cast<const uint8_t *>(serializedConfig.data()), reinterpret_cast<const uint8_t *>(serializedConfig.data()) + serializedConfig.size()); if (!overridesProtos.ParseFromArray(serialized.data(), static_cast<int>(serialized.size()))) { ALOGE("Failed to parse GpuConfig protobuf data."); } return overridesProtos; } } // namespace namespace android { std::string FeatureOverrideParser::getFeatureOverrideFilePath() const { const std::string kConfigFilePath = "/system/etc/angle/feature_config_vk.binarypb"; return kConfigFilePath; } bool FeatureOverrideParser::shouldReloadFeatureOverrides() const { std::string configFilePath = getFeatureOverrideFilePath(); struct stat fileStat{}; if (stat(getFeatureOverrideFilePath().c_str(), &fileStat) != 0) { ALOGE("Error getting file information for '%s': %s", getFeatureOverrideFilePath().c_str(), strerror(errno)); // stat'ing the file failed, so return false since reading it will also likely fail. return false; } return fileStat.st_mtime > mLastProtobufReadTime; } void FeatureOverrideParser::forceFileRead() { resetFeatureOverrides(mFeatureOverrides); mLastProtobufReadTime = 0; } void FeatureOverrideParser::parseFeatureOverrides() { const feature_override::FeatureOverrideProtos overridesProtos = readFeatureConfigProtos( getFeatureOverrideFilePath()); // Global feature overrides. for (const auto &featureConfigProto: overridesProtos.global_features()) { FeatureConfig featureConfig; initFeatureConfig(featureConfig, featureConfigProto); mFeatureOverrides.mGlobalFeatures.emplace_back(featureConfig); } // App-specific feature overrides. for (auto const &pkgConfigProto: overridesProtos.package_features()) { const std::string &packageName = pkgConfigProto.package_name(); if (mFeatureOverrides.mPackageFeatures.count(packageName)) { ALOGE("Package already has feature overrides! Skipping."); continue; } std::vector<FeatureConfig> featureConfigs; for (const auto &featureConfigProto: pkgConfigProto.feature_configs()) { FeatureConfig featureConfig; initFeatureConfig(featureConfig, featureConfigProto); featureConfigs.emplace_back(featureConfig); } mFeatureOverrides.mPackageFeatures[packageName] = featureConfigs; } mLastProtobufReadTime = std::chrono::system_clock::to_time_t( std::chrono::system_clock::now()); } FeatureOverrides FeatureOverrideParser::getFeatureOverrides() { if (shouldReloadFeatureOverrides()) { parseFeatureOverrides(); } return mFeatureOverrides; } } // namespace android services/gpuservice/feature_override/include/feature_override/FeatureOverrideParser.h 0 → 100644 +49 −0 Original line number Diff line number Diff line /* * Copyright 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef FEATURE_OVERRIDE_PARSER_H_ #define FEATURE_OVERRIDE_PARSER_H_ #include <ctime> #include <string> #include <vector> #include <graphicsenv/FeatureOverrides.h> namespace android { class FeatureOverrideParser { public: FeatureOverrideParser() = default; FeatureOverrideParser(const FeatureOverrideParser &) = default; virtual ~FeatureOverrideParser() = default; FeatureOverrides getFeatureOverrides(); void forceFileRead(); private: bool shouldReloadFeatureOverrides() const; void parseFeatureOverrides(); // Allow FeatureOverrideParserMock to override with the unit test file's path. virtual std::string getFeatureOverrideFilePath() const; std::time_t mLastProtobufReadTime = 0; FeatureOverrides mFeatureOverrides; }; } // namespace android #endif // FEATURE_OVERRIDE_PARSER_H_ services/gpuservice/feature_override/proto/feature_config.proto 0 → 100644 +53 −0 Original line number Diff line number Diff line /* * Copyright 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ syntax = "proto3"; package feature_override; option optimize_for = LITE_RUNTIME; /** * Feature Configuration * feature_name: Feature name (see external/angle/include/platform/autogen/FeaturesVk_autogen.h). * enabled: Either enable or disable the feature. */ message FeatureConfig { string feature_name = 1; bool enabled = 2; } /** * Package Configuration * feature_configs: List of features configs for the package. */ message PackageConfig { string package_name = 1; repeated FeatureConfig feature_configs = 2; } /** * Feature Overrides * global_features: Features to apply globally, for every package. * package_features: Features to apply for individual packages. */ message FeatureOverrideProtos { repeated FeatureConfig global_features = 1; repeated PackageConfig package_features = 2; } Loading
services/gpuservice/Android.bp +9 −0 Original line number Diff line number Diff line Loading @@ -19,10 +19,16 @@ cc_defaults { ], } cc_aconfig_library { name: "gpuservice_flags_c_lib", aconfig_declarations: "graphicsenv_flags", } cc_defaults { name: "libgpuservice_defaults", defaults: [ "gpuservice_defaults", "libfeatureoverride_deps", "libgfxstats_deps", "libgpumem_deps", "libgpumemtracer_deps", Loading @@ -40,8 +46,11 @@ cc_defaults { "libgraphicsenv", "liblog", "libutils", "server_configurable_flags", ], static_libs: [ "gpuservice_flags_c_lib", "libfeatureoverride", "libgfxstats", "libgpumem", "libgpumemtracer", Loading
services/gpuservice/feature_override/Android.bp 0 → 100644 +98 −0 Original line number Diff line number Diff line // Copyright 2024 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package { // See: http://go/android-license-faq // A large-scale-change added 'default_applicable_licenses' to import // all of the 'license_kinds' from "frameworks_native_license" // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_native_license"], } cc_defaults { name: "libfeatureoverride_deps", include_dirs: [ "external/protobuf", "external/protobuf/src", ], header_libs: [ "libbase_headers", ], shared_libs: [ "libbase", "libgraphicsenv", "liblog", ], static_libs: [ "libprotobuf-cpp-lite-ndk", ], } filegroup { name: "feature_config_proto_definitions", srcs: [ "proto/feature_config.proto", ], } genrule { name: "feature_config_proto_lite_gen_headers", srcs: [ ":feature_config_proto_definitions", ], tools: [ "aprotoc", ], cmd: "$(location aprotoc) " + "--proto_path=frameworks/native/services/gpuservice/feature_override " + "--cpp_out=lite=true:$(genDir)/frameworks/native/services/gpuservice/feature_override " + "$(locations :feature_config_proto_definitions)", out: [ "frameworks/native/services/gpuservice/feature_override/proto/feature_config.pb.h", ], export_include_dirs: [ "frameworks/native/services/gpuservice/feature_override/proto/", ], } cc_library_static { name: "libfeatureoverride", defaults: [ "libfeatureoverride_deps", ], srcs: [ ":feature_config_proto_definitions", "FeatureOverrideParser.cpp", ], local_include_dirs: [ "include", ], cflags: [ "-Wall", "-Werror", "-Wimplicit-fallthrough", ], cppflags: [ "-Wno-sign-compare", ], export_include_dirs: ["include"], proto: { type: "lite", static: true, }, generated_headers: [ "feature_config_proto_lite_gen_headers", ], }
services/gpuservice/feature_override/FeatureOverrideParser.cpp 0 → 100644 +141 −0 Original line number Diff line number Diff line /* * Copyright 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <feature_override/FeatureOverrideParser.h> #include <chrono> #include <fstream> #include <sstream> #include <string> #include <sys/stat.h> #include <vector> #include <graphicsenv/FeatureOverrides.h> #include <log/log.h> #include "feature_config.pb.h" namespace { void resetFeatureOverrides(android::FeatureOverrides &featureOverrides) { featureOverrides.mGlobalFeatures.clear(); featureOverrides.mPackageFeatures.clear(); } void initFeatureConfig(android::FeatureConfig &featureConfig, const feature_override::FeatureConfig &featureConfigProto) { featureConfig.mFeatureName = featureConfigProto.feature_name(); featureConfig.mEnabled = featureConfigProto.enabled(); } feature_override::FeatureOverrideProtos readFeatureConfigProtos(std::string configFilePath) { feature_override::FeatureOverrideProtos overridesProtos; std::ifstream protobufBinaryFile(configFilePath.c_str()); if (protobufBinaryFile.fail()) { ALOGE("Failed to open feature config file: `%s`.", configFilePath.c_str()); return overridesProtos; } std::stringstream buffer; buffer << protobufBinaryFile.rdbuf(); std::string serializedConfig = buffer.str(); std::vector<uint8_t> serialized( reinterpret_cast<const uint8_t *>(serializedConfig.data()), reinterpret_cast<const uint8_t *>(serializedConfig.data()) + serializedConfig.size()); if (!overridesProtos.ParseFromArray(serialized.data(), static_cast<int>(serialized.size()))) { ALOGE("Failed to parse GpuConfig protobuf data."); } return overridesProtos; } } // namespace namespace android { std::string FeatureOverrideParser::getFeatureOverrideFilePath() const { const std::string kConfigFilePath = "/system/etc/angle/feature_config_vk.binarypb"; return kConfigFilePath; } bool FeatureOverrideParser::shouldReloadFeatureOverrides() const { std::string configFilePath = getFeatureOverrideFilePath(); struct stat fileStat{}; if (stat(getFeatureOverrideFilePath().c_str(), &fileStat) != 0) { ALOGE("Error getting file information for '%s': %s", getFeatureOverrideFilePath().c_str(), strerror(errno)); // stat'ing the file failed, so return false since reading it will also likely fail. return false; } return fileStat.st_mtime > mLastProtobufReadTime; } void FeatureOverrideParser::forceFileRead() { resetFeatureOverrides(mFeatureOverrides); mLastProtobufReadTime = 0; } void FeatureOverrideParser::parseFeatureOverrides() { const feature_override::FeatureOverrideProtos overridesProtos = readFeatureConfigProtos( getFeatureOverrideFilePath()); // Global feature overrides. for (const auto &featureConfigProto: overridesProtos.global_features()) { FeatureConfig featureConfig; initFeatureConfig(featureConfig, featureConfigProto); mFeatureOverrides.mGlobalFeatures.emplace_back(featureConfig); } // App-specific feature overrides. for (auto const &pkgConfigProto: overridesProtos.package_features()) { const std::string &packageName = pkgConfigProto.package_name(); if (mFeatureOverrides.mPackageFeatures.count(packageName)) { ALOGE("Package already has feature overrides! Skipping."); continue; } std::vector<FeatureConfig> featureConfigs; for (const auto &featureConfigProto: pkgConfigProto.feature_configs()) { FeatureConfig featureConfig; initFeatureConfig(featureConfig, featureConfigProto); featureConfigs.emplace_back(featureConfig); } mFeatureOverrides.mPackageFeatures[packageName] = featureConfigs; } mLastProtobufReadTime = std::chrono::system_clock::to_time_t( std::chrono::system_clock::now()); } FeatureOverrides FeatureOverrideParser::getFeatureOverrides() { if (shouldReloadFeatureOverrides()) { parseFeatureOverrides(); } return mFeatureOverrides; } } // namespace android
services/gpuservice/feature_override/include/feature_override/FeatureOverrideParser.h 0 → 100644 +49 −0 Original line number Diff line number Diff line /* * Copyright 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef FEATURE_OVERRIDE_PARSER_H_ #define FEATURE_OVERRIDE_PARSER_H_ #include <ctime> #include <string> #include <vector> #include <graphicsenv/FeatureOverrides.h> namespace android { class FeatureOverrideParser { public: FeatureOverrideParser() = default; FeatureOverrideParser(const FeatureOverrideParser &) = default; virtual ~FeatureOverrideParser() = default; FeatureOverrides getFeatureOverrides(); void forceFileRead(); private: bool shouldReloadFeatureOverrides() const; void parseFeatureOverrides(); // Allow FeatureOverrideParserMock to override with the unit test file's path. virtual std::string getFeatureOverrideFilePath() const; std::time_t mLastProtobufReadTime = 0; FeatureOverrides mFeatureOverrides; }; } // namespace android #endif // FEATURE_OVERRIDE_PARSER_H_
services/gpuservice/feature_override/proto/feature_config.proto 0 → 100644 +53 −0 Original line number Diff line number Diff line /* * Copyright 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ syntax = "proto3"; package feature_override; option optimize_for = LITE_RUNTIME; /** * Feature Configuration * feature_name: Feature name (see external/angle/include/platform/autogen/FeaturesVk_autogen.h). * enabled: Either enable or disable the feature. */ message FeatureConfig { string feature_name = 1; bool enabled = 2; } /** * Package Configuration * feature_configs: List of features configs for the package. */ message PackageConfig { string package_name = 1; repeated FeatureConfig feature_configs = 2; } /** * Feature Overrides * global_features: Features to apply globally, for every package. * package_features: Features to apply for individual packages. */ message FeatureOverrideProtos { repeated FeatureConfig global_features = 1; repeated PackageConfig package_features = 2; }