1 /* 2 * Copyright (C) 2019 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 "link/ResourceExcluder.h" 18 19 #include <algorithm> 20 21 #include "DominatorTree.h" 22 #include "ResourceTable.h" 23 #include "trace/TraceBuffer.h" 24 25 using android::ConfigDescription; 26 27 namespace aapt { 28 29 namespace { 30 31 void RemoveIfExcluded(std::set<std::pair<ConfigDescription, int>>& excluded_configs_, 32 IAaptContext* context, 33 ResourceEntry* entry, 34 ResourceConfigValue* value) { 35 const ConfigDescription& config = value->config; 36 37 // If this entry is a default, ignore 38 if (config == ConfigDescription::DefaultConfig()) { 39 return; 40 } 41 42 for (auto& excluded_pair : excluded_configs_) { 43 44 const ConfigDescription& excluded_config = excluded_pair.first; 45 const int& excluded_diff = excluded_pair.second; 46 47 // Check whether config contains all flags in excluded config 48 int node_diff = config.diff(excluded_config); 49 int masked_diff = excluded_diff & node_diff; 50 51 if (masked_diff == 0) { 52 if (context->IsVerbose()) { 53 context->GetDiagnostics()->Note( 54 DiagMessage(value->value->GetSource()) 55 << "excluded resource \"" 56 << entry->name 57 << "\" with config " 58 << config.toString()); 59 } 60 value->value = {}; 61 return; 62 } 63 } 64 } 65 66 } // namespace 67 68 bool ResourceExcluder::Consume(IAaptContext* context, ResourceTable* table) { 69 TRACE_NAME("ResourceExcluder::Consume"); 70 for (auto& package : table->packages) { 71 for (auto& type : package->types) { 72 for (auto& entry : type->entries) { 73 for (auto& value : entry->values) { 74 RemoveIfExcluded(excluded_configs_, context, entry.get(), value.get()); 75 } 76 77 // Erase the values that were removed. 78 entry->values.erase( 79 std::remove_if( 80 entry->values.begin(), entry->values.end(), 81 [](const std::unique_ptr<ResourceConfigValue>& val) -> bool { 82 return val == nullptr || val->value == nullptr; 83 }), 84 entry->values.end()); 85 } 86 } 87 } 88 return true; 89 } 90 91 } // namespace aapt 92