| /* |
| * Copyright (C) 2014 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 com.android.build.gradle.internal.tasks.multidex |
| |
| import org.gradle.api.DefaultTask |
| import org.gradle.api.tasks.InputFile |
| import org.gradle.api.tasks.OutputFile |
| import org.gradle.api.tasks.TaskAction |
| import org.xml.sax.Attributes |
| import org.xml.sax.helpers.DefaultHandler |
| |
| import javax.xml.parsers.SAXParser |
| import javax.xml.parsers.SAXParserFactory |
| |
| class CreateManifestKeepList extends DefaultTask { |
| |
| @InputFile |
| File manifest |
| |
| @OutputFile |
| File outputFile |
| |
| Closure filter |
| |
| @TaskAction |
| void generateKeepListFromManifest() { |
| SAXParser parser = SAXParserFactory.newInstance().newSAXParser() |
| |
| Writer out = new BufferedWriter(new FileWriter(getOutputFile())) |
| try { |
| parser.parse(getManifest(), new ManifestHandler(out)) |
| |
| // add a couple of rules that cannot be easily parsed from the manifest. |
| out.write( |
| """-keep public class * extends android.app.backup.BackupAgent { |
| <init>(); |
| } |
| -keep public class * extends java.lang.annotation.Annotation { |
| *; |
| }""") |
| |
| } finally { |
| out.close() |
| } |
| } |
| |
| private static String DEFAULT_KEEP_SPEC = "{ <init>(); }" |
| private static Map<String, String> KEEP_SPECS = [ |
| 'application' : """{ |
| <init>(); |
| void attachBaseContext(android.content.Context); |
| }""", |
| 'activity' : DEFAULT_KEEP_SPEC, |
| 'service' : DEFAULT_KEEP_SPEC, |
| 'receiver' : DEFAULT_KEEP_SPEC, |
| 'provider' : DEFAULT_KEEP_SPEC, |
| 'instrumentation' : DEFAULT_KEEP_SPEC, |
| ] |
| |
| private class ManifestHandler extends DefaultHandler { |
| private Writer out |
| |
| ManifestHandler(Writer out) { |
| this.out = out |
| } |
| |
| @Override |
| void startElement(String uri, String localName, String qName, Attributes attr) { |
| String keepSpec = (String)CreateManifestKeepList.KEEP_SPECS[qName] |
| if (keepSpec) { |
| |
| boolean keepIt = true |
| if (CreateManifestKeepList.this.filter) { |
| // for ease of use, turn 'attr' into a simple map |
| Map<String, String> attrMap = [:] |
| for (int i = 0; i < attr.getLength(); i++) { |
| attrMap[attr.getQName(i)] = attr.getValue(i) |
| } |
| keepIt = CreateManifestKeepList.this.filter(qName, attrMap) |
| } |
| |
| if (keepIt) { |
| out.write((String)"-keep class ${attr.getValue('android:name')} $keepSpec\n") |
| } |
| } |
| } |
| } |
| } |