1 /* 2 * Copyright (C) 2015 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/Linkers.h" 18 19 #include <algorithm> 20 #include <iterator> 21 22 #include "android-base/logging.h" 23 24 #include "ResourceTable.h" 25 26 namespace aapt { 27 28 template <typename InputContainer, typename OutputIterator, typename Predicate> 29 OutputIterator move_if(InputContainer& input_container, OutputIterator result, Predicate pred) { 30 const auto last = input_container.end(); 31 auto new_end = std::find_if(input_container.begin(), input_container.end(), pred); 32 if (new_end == last) { 33 return result; 34 } 35 36 *result = std::move(*new_end); 37 38 auto first = new_end; 39 ++first; 40 41 for (; first != last; ++first) { 42 if (bool(pred(*first))) { 43 // We want to move this guy 44 *result = std::move(*first); 45 ++result; 46 } else { 47 // We want to keep this guy, but we will need to move it up the list to 48 // replace missing items. 49 *new_end = std::move(*first); 50 ++new_end; 51 } 52 } 53 54 input_container.erase(new_end, last); 55 return result; 56 } 57 58 bool PrivateAttributeMover::Consume(IAaptContext* context, ResourceTable* table) { 59 for (auto& package : table->packages) { 60 ResourceTableType* type = package->FindType(ResourceType::kAttr); 61 if (!type) { 62 continue; 63 } 64 65 if (type->visibility_level != Visibility::Level::kPublic) { 66 // No public attributes, so we can safely leave these private attributes 67 // where they are. 68 continue; 69 } 70 71 std::vector<std::unique_ptr<ResourceEntry>> private_attr_entries; 72 73 move_if(type->entries, std::back_inserter(private_attr_entries), 74 [](const std::unique_ptr<ResourceEntry>& entry) -> bool { 75 return entry->visibility.level != Visibility::Level::kPublic; 76 }); 77 78 if (private_attr_entries.empty()) { 79 // No private attributes. 80 continue; 81 } 82 83 ResourceTableType* priv_attr_type = package->FindOrCreateType(ResourceType::kAttrPrivate); 84 CHECK(priv_attr_type->entries.empty()); 85 priv_attr_type->entries = std::move(private_attr_entries); 86 } 87 return true; 88 } 89 90 } // namespace aapt 91