1a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski/* 2a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski * Copyright (C) 2015 The Android Open Source Project 3a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski * 4a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 5a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski * you may not use this file except in compliance with the License. 6a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski * You may obtain a copy of the License at 7a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski * 8a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 9a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski * 10a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski * Unless required by applicable law or agreed to in writing, software 11a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 12a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski * See the License for the specific language governing permissions and 14a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski * limitations under the License. 15a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski */ 16a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 17ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski#include "java/ProguardRules.h" 181ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 19a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski#include <memory> 20a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski#include <string> 21a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 22ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "android-base/macros.h" 23ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 24ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "util/Util.h" 25ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "xml/XmlDom.h" 26ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 27a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinskinamespace aapt { 28a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinskinamespace proguard { 29a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 30a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinskiclass BaseVisitor : public xml::Visitor { 31ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski public: 325c33fb5408d6c02dc2c73f53d89d1494fe04f208Adam Lesinski using xml::Visitor::Visit; 33a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 345c33fb5408d6c02dc2c73f53d89d1494fe04f208Adam Lesinski BaseVisitor(const Source& source, KeepSet* keep_set) : source_(source), keep_set_(keep_set) { 35ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 36ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 375c33fb5408d6c02dc2c73f53d89d1494fe04f208Adam Lesinski void Visit(xml::Element* node) override { 38ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (!node->namespace_uri.empty()) { 39ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski Maybe<xml::ExtractedPackage> maybe_package = 40ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski xml::ExtractPackageFromNamespace(node->namespace_uri); 41ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (maybe_package) { 42ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski // This is a custom view, let's figure out the class name from this. 43ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::string package = maybe_package.value().package + "." + node->name; 44ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (util::IsJavaClassName(package)) { 45ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski AddClass(node->line_number, package); 46a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 47ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 48ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } else if (util::IsJavaClassName(node->name)) { 49ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski AddClass(node->line_number, node->name); 50a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 51a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 52ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski for (const auto& child : node->children) { 53ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski child->Accept(this); 54a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 55ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 56a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 57ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski protected: 58ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski void AddClass(size_t line_number, const std::string& class_name) { 59ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski keep_set_->AddClass(Source(source_.path, line_number), class_name); 60ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 61a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 62ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski void AddMethod(size_t line_number, const std::string& method_name) { 63ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski keep_set_->AddMethod(Source(source_.path, line_number), method_name); 64ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 65ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 66ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski private: 67ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski DISALLOW_COPY_AND_ASSIGN(BaseVisitor); 68ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 69ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski Source source_; 70ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski KeepSet* keep_set_; 71a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski}; 72a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 73ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiclass LayoutVisitor : public BaseVisitor { 74ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski public: 755c33fb5408d6c02dc2c73f53d89d1494fe04f208Adam Lesinski LayoutVisitor(const Source& source, KeepSet* keep_set) : BaseVisitor(source, keep_set) { 765c33fb5408d6c02dc2c73f53d89d1494fe04f208Adam Lesinski } 77ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 785c33fb5408d6c02dc2c73f53d89d1494fe04f208Adam Lesinski void Visit(xml::Element* node) override { 79ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool check_class = false; 80ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool check_name = false; 81ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (node->namespace_uri.empty()) { 82f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski if (node->name == "view") { 83f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski check_class = true; 84f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski } else if (node->name == "fragment") { 85f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski check_class = check_name = true; 86f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski } 87ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } else if (node->namespace_uri == xml::kSchemaAndroid) { 88ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski check_name = node->name == "fragment"; 89a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 90a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 91ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski for (const auto& attr : node->attributes) { 92ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (check_class && attr.namespace_uri.empty() && attr.name == "class" && 93ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski util::IsJavaClassName(attr.value)) { 94ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski AddClass(node->line_number, attr.value); 95ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } else if (check_name && attr.namespace_uri == xml::kSchemaAndroid && 96ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski attr.name == "name" && util::IsJavaClassName(attr.value)) { 97ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski AddClass(node->line_number, attr.value); 98ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } else if (attr.namespace_uri == xml::kSchemaAndroid && 99ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski attr.name == "onClick") { 100ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski AddMethod(node->line_number, attr.value); 101ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 102ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 103a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 104ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski BaseVisitor::Visit(node); 105ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 106a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 107ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski private: 108ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski DISALLOW_COPY_AND_ASSIGN(LayoutVisitor); 109a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski}; 110a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 111f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinskiclass MenuVisitor : public BaseVisitor { 112f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski public: 113f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski MenuVisitor(const Source& source, KeepSet* keep_set) : BaseVisitor(source, keep_set) { 114f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski } 115f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 1165c33fb5408d6c02dc2c73f53d89d1494fe04f208Adam Lesinski void Visit(xml::Element* node) override { 117f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski if (node->namespace_uri.empty() && node->name == "item") { 118f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski for (const auto& attr : node->attributes) { 119f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski if (attr.namespace_uri == xml::kSchemaAndroid) { 120f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski if ((attr.name == "actionViewClass" || attr.name == "actionProviderClass") && 121f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski util::IsJavaClassName(attr.value)) { 122f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski AddClass(node->line_number, attr.value); 123f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski } else if (attr.name == "onClick") { 124f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski AddMethod(node->line_number, attr.value); 125f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski } 126f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski } 127f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski } 128f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski } 129f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 130f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski BaseVisitor::Visit(node); 131f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski } 132f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 133f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski private: 134f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski DISALLOW_COPY_AND_ASSIGN(MenuVisitor); 135f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski}; 136f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 137ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiclass XmlResourceVisitor : public BaseVisitor { 138ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski public: 1395c33fb5408d6c02dc2c73f53d89d1494fe04f208Adam Lesinski XmlResourceVisitor(const Source& source, KeepSet* keep_set) : BaseVisitor(source, keep_set) { 1405c33fb5408d6c02dc2c73f53d89d1494fe04f208Adam Lesinski } 141ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 1425c33fb5408d6c02dc2c73f53d89d1494fe04f208Adam Lesinski void Visit(xml::Element* node) override { 143ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool check_fragment = false; 144ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (node->namespace_uri.empty()) { 145ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski check_fragment = 146ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski node->name == "PreferenceScreen" || node->name == "header"; 147a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 148a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 149ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (check_fragment) { 150ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski xml::Attribute* attr = 151ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski node->FindAttribute(xml::kSchemaAndroid, "fragment"); 152ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (attr && util::IsJavaClassName(attr->value)) { 153ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski AddClass(node->line_number, attr->value); 154ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 155ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 156a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 157ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski BaseVisitor::Visit(node); 158ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 159a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 160ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski private: 161ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski DISALLOW_COPY_AND_ASSIGN(XmlResourceVisitor); 162a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski}; 163a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 164ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiclass TransitionVisitor : public BaseVisitor { 165ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski public: 1665c33fb5408d6c02dc2c73f53d89d1494fe04f208Adam Lesinski TransitionVisitor(const Source& source, KeepSet* keep_set) : BaseVisitor(source, keep_set) { 1675c33fb5408d6c02dc2c73f53d89d1494fe04f208Adam Lesinski } 168ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 1695c33fb5408d6c02dc2c73f53d89d1494fe04f208Adam Lesinski void Visit(xml::Element* node) override { 170ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool check_class = 1715c33fb5408d6c02dc2c73f53d89d1494fe04f208Adam Lesinski node->namespace_uri.empty() && (node->name == "transition" || node->name == "pathMotion"); 172ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (check_class) { 173ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski xml::Attribute* attr = node->FindAttribute({}, "class"); 174ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (attr && util::IsJavaClassName(attr->value)) { 175ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski AddClass(node->line_number, attr->value); 176ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 177a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 178a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 179ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski BaseVisitor::Visit(node); 180ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 181a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 182ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski private: 183ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski DISALLOW_COPY_AND_ASSIGN(TransitionVisitor); 184a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski}; 185a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 186ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskiclass ManifestVisitor : public BaseVisitor { 187ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski public: 188ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski ManifestVisitor(const Source& source, KeepSet* keep_set, bool main_dex_only) 189ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski : BaseVisitor(source, keep_set), main_dex_only_(main_dex_only) {} 190ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 1915c33fb5408d6c02dc2c73f53d89d1494fe04f208Adam Lesinski void Visit(xml::Element* node) override { 192ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (node->namespace_uri.empty()) { 193ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool get_name = false; 194ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (node->name == "manifest") { 195ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski xml::Attribute* attr = node->FindAttribute({}, "package"); 196ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (attr) { 197ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski package_ = attr->value; 198ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 199ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } else if (node->name == "application") { 200ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski get_name = true; 2015c33fb5408d6c02dc2c73f53d89d1494fe04f208Adam Lesinski xml::Attribute* attr = node->FindAttribute(xml::kSchemaAndroid, "backupAgent"); 202ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (attr) { 2035c33fb5408d6c02dc2c73f53d89d1494fe04f208Adam Lesinski Maybe<std::string> result = util::GetFullyQualifiedClassName(package_, attr->value); 204ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (result) { 205ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski AddClass(node->line_number, result.value()); 206ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 207ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 208ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (main_dex_only_) { 2095c33fb5408d6c02dc2c73f53d89d1494fe04f208Adam Lesinski xml::Attribute* default_process = node->FindAttribute(xml::kSchemaAndroid, "process"); 210ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (default_process) { 211ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski default_process_ = default_process->value; 212ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 213ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 214ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } else if (node->name == "activity" || node->name == "service" || 215ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski node->name == "receiver" || node->name == "provider") { 216ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski get_name = true; 217ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 218ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (main_dex_only_) { 2195c33fb5408d6c02dc2c73f53d89d1494fe04f208Adam Lesinski xml::Attribute* component_process = node->FindAttribute(xml::kSchemaAndroid, "process"); 220a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 221ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const std::string& process = 222ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski component_process ? component_process->value : default_process_; 223ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski get_name = !process.empty() && process[0] != ':'; 224a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 225ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } else if (node->name == "instrumentation") { 226ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski get_name = true; 227ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 228ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 229ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (get_name) { 230ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski xml::Attribute* attr = node->FindAttribute(xml::kSchemaAndroid, "name"); 231ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski get_name = attr != nullptr; 232ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 233ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (get_name) { 2345c33fb5408d6c02dc2c73f53d89d1494fe04f208Adam Lesinski Maybe<std::string> result = util::GetFullyQualifiedClassName(package_, attr->value); 235ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (result) { 236ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski AddClass(node->line_number, result.value()); 237ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 238ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 239ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 240a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 241ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski BaseVisitor::Visit(node); 242ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 243ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 244ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski private: 245ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski DISALLOW_COPY_AND_ASSIGN(ManifestVisitor); 246a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 247ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::string package_; 248ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const bool main_dex_only_; 249ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski std::string default_process_; 250a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski}; 251a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 2525c33fb5408d6c02dc2c73f53d89d1494fe04f208Adam Lesinskibool CollectProguardRulesForManifest(const Source& source, xml::XmlResource* res, KeepSet* keep_set, 253ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski bool main_dex_only) { 254ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski ManifestVisitor visitor(source, keep_set, main_dex_only); 255ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (res->root) { 256ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski res->root->Accept(&visitor); 257ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return true; 258ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 259ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return false; 260a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski} 261a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 2625c33fb5408d6c02dc2c73f53d89d1494fe04f208Adam Lesinskibool CollectProguardRules(const Source& source, xml::XmlResource* res, KeepSet* keep_set) { 263ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (!res->root) { 264ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return false; 265ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 266a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 267ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski switch (res->file.name.type) { 268ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski case ResourceType::kLayout: { 269ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski LayoutVisitor visitor(source, keep_set); 270ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski res->root->Accept(&visitor); 271ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski break; 272ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 273a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 274ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski case ResourceType::kXml: { 275ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski XmlResourceVisitor visitor(source, keep_set); 276ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski res->root->Accept(&visitor); 277ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski break; 278ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 279a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 280ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski case ResourceType::kTransition: { 281ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski TransitionVisitor visitor(source, keep_set); 282ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski res->root->Accept(&visitor); 283ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski break; 284a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 285ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 286f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski case ResourceType::kMenu: { 287f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski MenuVisitor visitor(source, keep_set); 288f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski res->root->Accept(&visitor); 289f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski break; 290f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski } 291f762df257574231ffd08679a69e9cf62fe143dcdAdam Lesinski 292ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski default: 293ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski break; 294ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 295ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return true; 296a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski} 297a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 298ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinskibool WriteKeepSet(std::ostream* out, const KeepSet& keep_set) { 299ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski for (const auto& entry : keep_set.keep_set_) { 300ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski for (const Source& source : entry.second) { 301ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski *out << "# Referenced at " << source << "\n"; 302a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 303ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski *out << "-keep class " << entry.first << " { <init>(...); }\n" << std::endl; 304ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 305a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 306ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski for (const auto& entry : keep_set.keep_method_set_) { 307ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski for (const Source& source : entry.second) { 308ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski *out << "# Referenced at " << source << "\n"; 309a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 3105c33fb5408d6c02dc2c73f53d89d1494fe04f208Adam Lesinski *out << "-keepclassmembers class * { *** " << entry.first << "(...); }\n" << std::endl; 311ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski } 312ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return true; 313a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski} 314a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 315ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski} // namespace proguard 316ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski} // namespace aapt 317