Add YouTube 14.44
Update parsing of configuration files as well.
Change-Id: I9d63a69448ff7e60d243a8b47ad300209ee62b38
diff --git a/build.gradle b/build.gradle
index 89e6798..2e64458 100644
--- a/build.gradle
+++ b/build.gradle
@@ -413,7 +413,8 @@
"youtube/youtube.android_12.17",
"youtube/youtube.android_12.22",
"youtube/youtube.android_13.37",
- "youtube/youtube.android_14.19"
+ "youtube/youtube.android_14.19",
+ "youtube/youtube.android_14.44"
],
]
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
index 0f62be2..0652a33 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
@@ -57,9 +57,8 @@
"target",
"maximuminlinedcodelength");
- private static final List<String> IGNORED_OPTIONAL_SINGLE_ARG_OPTIONS = ImmutableList.of(
- "runtype",
- "laststageoutput");
+ private static final List<String> IGNORED_OPTIONAL_SINGLE_ARG_OPTIONS =
+ ImmutableList.of("runtype", "laststageoutput", "maximumremovedandroidloglevel");
private static final List<String> IGNORED_FLAG_OPTIONS = ImmutableList.of(
"forceprocessing",
@@ -249,6 +248,9 @@
} else if (acceptString("checkdiscard")) {
ProguardCheckDiscardRule rule = parseCheckDiscardRule(optionStart);
configurationBuilder.addRule(rule);
+ } else if (acceptString("checkenumstringsdiscarded")) {
+ // Not supported, ignore.
+ parseCheckDiscardRule(optionStart);
} else if (acceptString("keepdirectories")) {
configurationBuilder.enableKeepDirectories();
parsePathFilter(configurationBuilder::addKeepDirectories);
@@ -501,7 +503,8 @@
return true;
}
- private boolean parseIgnoredOption(TextPosition optionStart) {
+ private boolean parseIgnoredOption(TextPosition optionStart)
+ throws ProguardRuleParserException {
return Iterables.any(IGNORED_SINGLE_ARG_OPTIONS, this::skipOptionWithSingleArg)
|| Iterables.any(
IGNORED_OPTIONAL_SINGLE_ARG_OPTIONS, this::skipOptionWithOptionalSingleArg)
@@ -596,7 +599,8 @@
}
- private boolean parseOptimizationOption(TextPosition optionStart) {
+ private boolean parseOptimizationOption(TextPosition optionStart)
+ throws ProguardRuleParserException {
if (!acceptString("optimizations")) {
return false;
}
@@ -609,11 +613,19 @@
return true;
}
- private void skipOptimizationName() {
+ private void skipOptimizationName() throws ProguardRuleParserException {
+ char quote = acceptQuoteIfPresent();
+ if (isQuote(quote)) {
+ skipWhitespace();
+ }
if (acceptChar('!')) {
skipWhitespace();
}
acceptString(next -> Character.isAlphabetic(next) || next == '/' || next == '*');
+ if (isQuote(quote)) {
+ skipWhitespace();
+ expectClosingQuote(quote);
+ }
}
private void skipSingleArgument() {
@@ -1745,14 +1757,22 @@
private List<String> acceptPatternList() throws ProguardRuleParserException {
List<String> patterns = new ArrayList<>();
skipWhitespace();
+ char quote = acceptQuoteIfPresent();
String pattern = acceptPattern();
+ if (isQuote(quote)) {
+ expectClosingQuote(quote);
+ }
while (pattern != null) {
patterns.add(pattern);
skipWhitespace();
- TextPosition start = getPosition();
if (acceptChar(',')) {
skipWhitespace();
+ TextPosition start = getPosition();
+ quote = acceptQuoteIfPresent();
pattern = acceptPattern();
+ if (isQuote(quote)) {
+ expectClosingQuote(quote);
+ }
if (pattern == null) {
throw parseError("Expected list element", start);
}
diff --git a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
index fae56af..1a37fc5 100644
--- a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
@@ -1044,16 +1044,38 @@
ImmutableList.of(
"-optimizations",
"-optimizations xxx",
+ "-optimizations \"xxx\"",
+ "-optimizations 'xxx'",
"-optimizations xxx",
+ "-optimizations \" xxx\"",
+ "-optimizations ' xxx'",
"-optimizations xxx/yyy",
+ "-optimizations \"xxx/yyy\"",
+ "-optimizations 'xxx/yyy'",
"-optimizations xxx/yyy",
+ "-optimizations \" xxx/yyy\"",
+ "-optimizations ' xxx/yyy'",
"-optimizations xxx/yyy,zzz*",
+ "-optimizations \"xxx/yyy\",\"zzz*\"",
+ "-optimizations 'xxx/yyy','zzz*'",
"-optimizations xxx/yyy , zzz*",
+ "-optimizations \"xxx/yyy \",\" zzz*\"",
+ "-optimizations 'xxx/yyy ',' zzz*'",
"-optimizations !xxx",
+ "-optimizations \"!xxx\"",
+ "-optimizations '!xxx'",
"-optimizations ! xxx",
+ "-optimizations \" ! xxx\"",
+ "-optimizations ' ! xxx'",
"-optimizations !xxx,!yyy",
+ "-optimizations \"!xxx\",\"!yyy\"",
+ "-optimizations '!xxx','!yyy'",
"-optimizations ! xxx, ! yyy",
- "-optimizations !code/simplification/advanced,code/simplification/*")) {
+ "-optimizations \" ! xxx\", \" ! yyy\"",
+ "-optimizations ' ! xxx', ' ! yyy'",
+ "-optimizations !code/simplification/advanced,code/simplification/*",
+ "-optimizations \"!code/simplification/advanced\",\"code/simplification/*\"",
+ "-optimizations '!code/simplification/advanced','code/simplification/*'")) {
reset();
Path proguardConfig = writeTextToTempFile(option);
parser.parse(proguardConfig);
@@ -1294,11 +1316,21 @@
public void parseKeepattributes() {
List<String> xxxYYY = ImmutableList.of("xxx", "yyy");
testKeepattributes(xxxYYY, "-keepattributes xxx,yyy");
+ testKeepattributes(xxxYYY, "-keepattributes \"xxx\",\"yyy\"");
+ testKeepattributes(xxxYYY, "-keepattributes 'xxx','yyy'");
testKeepattributes(xxxYYY, "-keepattributes xxx, yyy");
+ testKeepattributes(xxxYYY, "-keepattributes \"xxx\", \"yyy\"");
+ testKeepattributes(xxxYYY, "-keepattributes 'xxx', 'yyy'");
testKeepattributes(xxxYYY, "-keepattributes xxx ,yyy");
testKeepattributes(xxxYYY, "-keepattributes xxx , yyy");
+ testKeepattributes(xxxYYY, "-keepattributes \"xxx\" , \"yyy\"");
+ testKeepattributes(xxxYYY, "-keepattributes 'xxx' , 'yyy'");
testKeepattributes(xxxYYY, "-keepattributes xxx , yyy ");
+ testKeepattributes(xxxYYY, "-keepattributes \"xxx\" , \"yyy\" ");
+ testKeepattributes(xxxYYY, "-keepattributes 'xxx' , 'yyy' ");
testKeepattributes(xxxYYY, "-keepattributes xxx , yyy \n");
+ testKeepattributes(xxxYYY, "-keepattributes \"xxx\" , \"yyy\" \n");
+ testKeepattributes(xxxYYY, "-keepattributes 'xxx' , 'yyy' \n");
String config =
"-keepattributes Exceptions,InnerClasses,Signature,Deprecated,\n"
+ " SourceFile,LineNumberTable,*Annotation*,EnclosingMethod\n";
@@ -1306,6 +1338,14 @@
"Exceptions", "InnerClasses", "Signature", "Deprecated",
"SourceFile", "LineNumberTable", "*Annotation*", "EnclosingMethod");
testKeepattributes(expected, config);
+ config =
+ "-keepattributes \"Exceptions\",\"InnerClasses\",\"Signature\",\"Deprecated\",\n"
+ + " \"SourceFile\",\"LineNumberTable\",\"*Annotation*\",\"EnclosingMethod\"\n";
+ testKeepattributes(expected, config);
+ config =
+ "-keepattributes 'Exceptions','InnerClasses','Signature','Deprecated',\n"
+ + " 'SourceFile','LineNumberTable','*Annotation*','EnclosingMethod'\n";
+ testKeepattributes(expected, config);
}
private void testKeeppackagenames(ProguardPackageNameList expected, String config) {
@@ -2872,4 +2912,14 @@
MatchSpecificType specificTypeMatcher = (MatchSpecificType) singleClassNameList.className;
assertEquals("foo.bar$Baz", specificTypeMatcher.type.toSourceString());
}
+
+ @Test
+ public void parseCheckenumstringsdiscarded() throws Exception {
+ Path proguardConfig =
+ writeTextToTempFile("-checkenumstringsdiscarded @com.example.SomeAnnotation enum *");
+ ProguardConfigurationParser parser =
+ new ProguardConfigurationParser(new DexItemFactory(), reporter);
+ parser.parse(proguardConfig);
+ verifyParserEndsCleanly();
+ }
}
\ No newline at end of file
diff --git a/third_party/youtube/youtube.android_14.44.tar.gz.sha1 b/third_party/youtube/youtube.android_14.44.tar.gz.sha1
new file mode 100644
index 0000000..bdf9586
--- /dev/null
+++ b/third_party/youtube/youtube.android_14.44.tar.gz.sha1
@@ -0,0 +1 @@
+368f0029be6a0a2629ba8f05ea6954a3a859115e
\ No newline at end of file
diff --git a/tools/run_on_app.py b/tools/run_on_app.py
index d93e3c0..32ff432 100755
--- a/tools/run_on_app.py
+++ b/tools/run_on_app.py
@@ -15,7 +15,7 @@
import gmscore_data
import golem
import nest_data
-from sanitize_libraries import SanitizeLibraries
+from sanitize_libraries import SanitizeLibraries, SanitizeLibrariesInPgconf
import toolhelper
import utils
import youtube_data
@@ -386,6 +386,19 @@
return 'deploy' if options.compiler == 'r8' else 'proguarded'
return options.type
+def check_no_injars_and_no_libraryjars(pgconfs):
+ # Ensure that there are no -injars or -libraryjars in the configuration.
+ for pgconf in pgconfs:
+ pgconf_dirname = os.path.abspath(os.path.dirname(pgconf))
+ with open(pgconf) as pgconf_file:
+ for line in pgconf_file:
+ trimmed = line.strip()
+ if trimmed.startswith('-injars'):
+ raise Exception("Unexpected -injars found in " + pgconf)
+ elif trimmed.startswith('-libraryjars'):
+ raise Exception("Unexpected -libraryjars found in " + pgconf)
+
+
def run_with_options(options, args, extra_args=None, stdout=None, quiet=False):
if extra_args is None:
extra_args = []
@@ -451,11 +464,20 @@
if 'pgconf' in values and not options.k:
sanitized_lib_path = os.path.join(
os.path.abspath(outdir), 'sanitized_lib.jar')
- sanitized_pgconf_path = os.path.join(
- os.path.abspath(outdir), 'sanitized.config')
- SanitizeLibraries(
- sanitized_lib_path, sanitized_pgconf_path, values['pgconf'])
- args.extend(['--pg-conf', sanitized_pgconf_path])
+ if 'no_inputs_in_pgconf' in values and values['no_inputs_in_pgconf']:
+ check_no_injars_and_no_libraryjars(values['pgconf'])
+ SanitizeLibraries(
+ sanitized_lib_path, values['libraries'], values['inputs'])
+ args.extend(['--lib', sanitized_lib_path])
+ for lib in values['pgconf']:
+ args.extend(['--pg-conf', lib])
+ args.extend(values['inputs'])
+ else:
+ sanitized_pgconf_path = os.path.join(
+ os.path.abspath(outdir), 'sanitized.config')
+ SanitizeLibrariesInPgconf(
+ sanitized_lib_path, sanitized_pgconf_path, values['pgconf'])
+ args.extend(['--pg-conf', sanitized_pgconf_path])
app_provided_pg_conf = True
if options.k:
args.extend(['--pg-conf', options.k])
@@ -470,7 +492,8 @@
extra_args.append('-Dcom.android.tools.r8.generatedMessageLiteShrinking=1')
extra_args.append('-Dcom.android.tools.r8.stringSwitchConversion=1')
- if not options.no_libraries and 'libraries' in values:
+ if (not options.no_libraries and 'libraries' in values
+ 'no_inputs_in_pgconf' in values and not values['no_inputs_in_pgconf']):
for lib in values['libraries']:
args.extend(['--lib', lib])
diff --git a/tools/sanitize_libraries.py b/tools/sanitize_libraries.py
index e67a06e..87aa887 100755
--- a/tools/sanitize_libraries.py
+++ b/tools/sanitize_libraries.py
@@ -13,7 +13,8 @@
# To make these apps work with R8 simulate program classes before library
# classes by creating a new library jar which have all the provided library
# classes which are not also in program classes.
-def SanitizeLibraries(sanitized_lib_path, sanitized_pgconf_path, pgconfs):
+def SanitizeLibrariesInPgconf(
+ sanitized_lib_path, sanitized_pgconf_path, pgconfs):
injars = []
libraryjars = []
@@ -44,6 +45,11 @@
else:
sanitized_pgconf.write(line)
+ SanitizeLibraries(sanitized_lib_path, libraryjars, injars)
+
+
+def SanitizeLibraries(sanitized_lib_path, libraryjars, injars):
+
program_entries = set()
library_entries = set()
@@ -61,7 +67,6 @@
library_entries.add(zipinfo.filename)
output_zf.writestr(zipinfo, input_zf.read(zipinfo))
- return sanitized_pgconf_path
def main(argv):
if (len(argv) < 3):
diff --git a/tools/youtube_data.py b/tools/youtube_data.py
index 94a97ce..f8e936f 100644
--- a/tools/youtube_data.py
+++ b/tools/youtube_data.py
@@ -24,6 +24,9 @@
V14_19_BASE = os.path.join(BASE, 'youtube.android_14.19')
V14_19_PREFIX = os.path.join(V14_19_BASE, 'YouTubeRelease')
+V14_44_BASE = os.path.join(BASE, 'youtube.android_14.44')
+V14_44_PREFIX = os.path.join(V14_44_BASE, 'YouTubeRelease')
+
# NOTE: we always use android.jar for SDK v25, later we might want to revise it
# to use proper android.jar version for each of youtube version separately.
ANDROID_JAR = utils.get_android_jar(25)
@@ -146,4 +149,35 @@
'min-api' : ANDROID_L_API,
}
},
+ '14.44': {
+ 'dex' : {
+ 'inputs': [os.path.join(V14_44_BASE, 'YouTubeRelease_unsigned.apk')],
+ 'pgmap': '%s_proguard.map' % V14_44_PREFIX,
+ 'libraries' : [ANDROID_JAR],
+ 'min-api' : ANDROID_L_API,
+ },
+ 'deploy' : {
+ # -injars and -libraryjars are no longer used in the configuration. Instead
+ # they are taken directly from 'inputs' and 'libraries'.
+ 'no_inputs_in_pgconf': True,
+ 'inputs': ['%s_deploy.jar' % V14_44_PREFIX],
+ 'libraries' : [os.path.join(V14_44_BASE, 'legacy_YouTubeRelease_combined_library_jars.jar')],
+ 'pgconf': [
+ '%s_proguard.config' % V14_44_PREFIX,
+ '%s/proguardsettings/YouTubeRelease_proguard.config' % utils.THIRD_PARTY],
+ 'proto-shrinking': 1,
+ # Build for native multi dex, as Currently R8 cannot meet the main-dex
+ # constraints.
+ #'maindexrules' : [
+ # os.path.join(V14_44_BASE, 'mainDexClasses.rules'),
+ # os.path.join(V14_44_BASE, 'main-dex-classes-release-optimized.cfg'),
+ # os.path.join(V14_44_BASE, 'main_dex_YouTubeRelease_proguard.cfg')],
+ 'min-api' : ANDROID_L_API,
+ },
+ 'proguarded' : {
+ 'inputs': ['%s_proguard.jar' % V14_44_PREFIX],
+ 'pgmap': '%s_proguard.map' % V14_44_PREFIX,
+ 'min-api' : ANDROID_L_API,
+ }
+ },
}