ProguardRules.cpp revision ca5638fd85098c3d0a699492751043545f75553a
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 17a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski#include "XmlDom.h" 18a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 19ca5638fd85098c3d0a699492751043545f75553aAdam Lesinski#include "java/ProguardRules.h" 201ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "util/Util.h" 211ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 22a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski#include <memory> 23a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski#include <string> 24a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 25a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinskinamespace aapt { 26a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinskinamespace proguard { 27a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 28a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinskiconstexpr const char16_t* kSchemaAndroid = u"http://schemas.android.com/apk/res/android"; 29a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 30a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinskiclass BaseVisitor : public xml::Visitor { 31a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinskipublic: 32a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski BaseVisitor(const Source& source, KeepSet* keepSet) : mSource(source), mKeepSet(keepSet) { 33a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 34a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 35a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski virtual void visit(xml::Text*) override {}; 36a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 37a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski virtual void visit(xml::Namespace* node) override { 38a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski for (const auto& child : node->children) { 39a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski child->accept(this); 40a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 41a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 42a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 43a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski virtual void visit(xml::Element* node) override { 44a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski if (!node->namespaceUri.empty()) { 45a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski Maybe<std::u16string> maybePackage = util::extractPackageFromNamespace( 46a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski node->namespaceUri); 47a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski if (maybePackage) { 48a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski // This is a custom view, let's figure out the class name from this. 49a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski std::u16string package = maybePackage.value() + u"." + node->name; 50a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski if (util::isJavaClassName(package)) { 51a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski addClass(node->lineNumber, package); 52a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 53a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 54a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } else if (util::isJavaClassName(node->name)) { 55a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski addClass(node->lineNumber, node->name); 56a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 57a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 58a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski for (const auto& child: node->children) { 59a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski child->accept(this); 60a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 61a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 62a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 63a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinskiprotected: 64a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski void addClass(size_t lineNumber, const std::u16string& className) { 651ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski mKeepSet->addClass(Source(mSource.path, lineNumber), className); 66a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 67a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 68a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski void addMethod(size_t lineNumber, const std::u16string& methodName) { 691ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski mKeepSet->addMethod(Source(mSource.path, lineNumber), methodName); 70a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 71a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 72a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinskiprivate: 73a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski Source mSource; 74a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski KeepSet* mKeepSet; 75a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski}; 76a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 77a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinskistruct LayoutVisitor : public BaseVisitor { 78a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski LayoutVisitor(const Source& source, KeepSet* keepSet) : BaseVisitor(source, keepSet) { 79a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 80a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 81a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski virtual void visit(xml::Element* node) override { 82a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski bool checkClass = false; 83a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski bool checkName = false; 84a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski if (node->namespaceUri.empty()) { 85a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski checkClass = node->name == u"view" || node->name == u"fragment"; 86a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } else if (node->namespaceUri == kSchemaAndroid) { 87a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski checkName = node->name == u"fragment"; 88a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 89a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 90a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski for (const auto& attr : node->attributes) { 91a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski if (checkClass && attr.namespaceUri.empty() && attr.name == u"class" && 92a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski util::isJavaClassName(attr.value)) { 93a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski addClass(node->lineNumber, attr.value); 94a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } else if (checkName && attr.namespaceUri == kSchemaAndroid && attr.name == u"name" && 95a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski util::isJavaClassName(attr.value)) { 96a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski addClass(node->lineNumber, attr.value); 97a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } else if (attr.namespaceUri == kSchemaAndroid && attr.name == u"onClick") { 98a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski addMethod(node->lineNumber, attr.value); 99a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 100a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 101a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 102a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski BaseVisitor::visit(node); 103a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 104a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski}; 105a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 106a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinskistruct XmlResourceVisitor : public BaseVisitor { 107a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski XmlResourceVisitor(const Source& source, KeepSet* keepSet) : BaseVisitor(source, keepSet) { 108a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 109a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 110a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski virtual void visit(xml::Element* node) override { 111a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski bool checkFragment = false; 112a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski if (node->namespaceUri.empty()) { 113a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski checkFragment = node->name == u"PreferenceScreen" || node->name == u"header"; 114a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 115a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 116a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski if (checkFragment) { 117a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski xml::Attribute* attr = node->findAttribute(kSchemaAndroid, u"fragment"); 118a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski if (attr && util::isJavaClassName(attr->value)) { 119a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski addClass(node->lineNumber, attr->value); 120a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 121a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 122a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 123a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski BaseVisitor::visit(node); 124a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 125a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski}; 126a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 127a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinskistruct TransitionVisitor : public BaseVisitor { 128a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski TransitionVisitor(const Source& source, KeepSet* keepSet) : BaseVisitor(source, keepSet) { 129a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 130a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 131a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski virtual void visit(xml::Element* node) override { 132a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski bool checkClass = node->namespaceUri.empty() && 133a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski (node->name == u"transition" || node->name == u"pathMotion"); 134a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski if (checkClass) { 135a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski xml::Attribute* attr = node->findAttribute({}, u"class"); 136a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski if (attr && util::isJavaClassName(attr->value)) { 137a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski addClass(node->lineNumber, attr->value); 138a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 139a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 140a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 141a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski BaseVisitor::visit(node); 142a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 143a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski}; 144a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 145a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinskistruct ManifestVisitor : public BaseVisitor { 146a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski ManifestVisitor(const Source& source, KeepSet* keepSet) : BaseVisitor(source, keepSet) { 147a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 148a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 149a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski virtual void visit(xml::Element* node) override { 150a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski if (node->namespaceUri.empty()) { 151a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski bool getName = false; 152a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski if (node->name == u"manifest") { 153a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski xml::Attribute* attr = node->findAttribute({}, u"package"); 154a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski if (attr) { 155a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski mPackage = attr->value; 156a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 157a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } else if (node->name == u"application") { 158a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski getName = true; 159a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski xml::Attribute* attr = node->findAttribute(kSchemaAndroid, u"backupAgent"); 160a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski if (attr) { 161a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski Maybe<std::u16string> result = util::getFullyQualifiedClassName(mPackage, 162a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski attr->value); 163a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski if (result) { 164a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski addClass(node->lineNumber, result.value()); 165a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 166a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 167a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } else if (node->name == u"activity" || node->name == u"service" || 168a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski node->name == u"receiver" || node->name == u"provider" || 169a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski node->name == u"instrumentation") { 170a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski getName = true; 171a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 172a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 173a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski if (getName) { 174a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski xml::Attribute* attr = node->findAttribute(kSchemaAndroid, u"name"); 175a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski if (attr) { 176a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski Maybe<std::u16string> result = util::getFullyQualifiedClassName(mPackage, 177a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski attr->value); 178a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski if (result) { 179a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski addClass(node->lineNumber, result.value()); 180a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 181a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 182a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 183a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 184a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski BaseVisitor::visit(node); 185a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 186a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 187a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski std::u16string mPackage; 188a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski}; 189a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 1901ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskibool collectProguardRulesForManifest(const Source& source, XmlResource* res, KeepSet* keepSet) { 191a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski ManifestVisitor visitor(source, keepSet); 1921ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski if (res->root) { 1931ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski res->root->accept(&visitor); 1941ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski return true; 1951ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 1961ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski return false; 197a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski} 198a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 1991ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskibool collectProguardRules(const Source& source, XmlResource* res, KeepSet* keepSet) { 2001ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski if (!res->root) { 2011ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski return false; 2021ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski } 2031ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski 2041ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski switch (res->file.name.type) { 205a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski case ResourceType::kLayout: { 206a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski LayoutVisitor visitor(source, keepSet); 2071ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski res->root->accept(&visitor); 208a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski break; 209a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 210a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 211a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski case ResourceType::kXml: { 212a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski XmlResourceVisitor visitor(source, keepSet); 2131ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski res->root->accept(&visitor); 214a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski break; 215a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 216a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 217a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski case ResourceType::kTransition: { 218a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski TransitionVisitor visitor(source, keepSet); 2191ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski res->root->accept(&visitor); 220a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski break; 221a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 222a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 223a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski default: 224a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski break; 225a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 226a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski return true; 227a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski} 228a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 229a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinskibool writeKeepSet(std::ostream* out, const KeepSet& keepSet) { 230a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski for (const auto& entry : keepSet.mKeepSet) { 2311ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski for (const Source& source : entry.second) { 232a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski *out << "// Referenced at " << source << "\n"; 233a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 234a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski *out << "-keep class " << entry.first << " { <init>(...); }\n" << std::endl; 235a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 236a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 237a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski for (const auto& entry : keepSet.mKeepMethodSet) { 2381ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski for (const Source& source : entry.second) { 239a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski *out << "// Referenced at " << source << "\n"; 240a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 241a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski *out << "-keepclassmembers class * { *** " << entry.first << "(...); }\n" << std::endl; 242a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski } 243a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski return true; 244a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski} 245a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski 246a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski} // namespace proguard 247a1ad4a812a87642ad259ff4478159e8cc8194680Adam Lesinski} // namespace aapt 248