1// Copyright 2022 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
17import (
18	"fmt"
19	"testing"
20
21	"android/soong/android"
22
23	"github.com/google/blueprint/proptools"
24)
25
26func TestR8(t *testing.T) {
27	result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
28		android_app {
29			name: "app",
30			srcs: ["foo.java"],
31			libs: ["lib"],
32			static_libs: ["static_lib"],
33			platform_apis: true,
34		}
35
36		android_app {
37			name: "stable_app",
38			srcs: ["foo.java"],
39			sdk_version: "current",
40			min_sdk_version: "31",
41		}
42
43		android_app {
44			name: "core_platform_app",
45			srcs: ["foo.java"],
46			sdk_version: "core_platform",
47			min_sdk_version: "31",
48		}
49
50		java_library {
51			name: "lib",
52			srcs: ["foo.java"],
53		}
54
55		java_library {
56			name: "static_lib",
57			srcs: ["foo.java"],
58		}
59	`)
60
61	app := result.ModuleForTests("app", "android_common")
62	stableApp := result.ModuleForTests("stable_app", "android_common")
63	corePlatformApp := result.ModuleForTests("core_platform_app", "android_common")
64	lib := result.ModuleForTests("lib", "android_common")
65	staticLib := result.ModuleForTests("static_lib", "android_common")
66
67	appJavac := app.Rule("javac")
68	appR8 := app.Rule("r8")
69	stableAppR8 := stableApp.Rule("r8")
70	corePlatformAppR8 := corePlatformApp.Rule("r8")
71	libHeader := lib.Output("turbine-combined/lib.jar").Output
72	staticLibHeader := staticLib.Output("turbine-combined/static_lib.jar").Output
73
74	android.AssertStringDoesContain(t, "expected lib header jar in app javac classpath",
75		appJavac.Args["classpath"], libHeader.String())
76	android.AssertStringDoesContain(t, "expected static_lib header jar in app javac classpath",
77		appJavac.Args["classpath"], staticLibHeader.String())
78
79	android.AssertStringDoesContain(t, "expected lib header jar in app r8 classpath",
80		appR8.Args["r8Flags"], libHeader.String())
81	android.AssertStringDoesNotContain(t, "expected no static_lib header jar in app r8 classpath",
82		appR8.Args["r8Flags"], staticLibHeader.String())
83	android.AssertStringDoesContain(t, "expected -ignorewarnings in app r8 flags",
84		appR8.Args["r8Flags"], "-ignorewarnings")
85	android.AssertStringDoesContain(t, "expected --android-platform-build in app r8 flags",
86		appR8.Args["r8Flags"], "--android-platform-build")
87	android.AssertStringDoesNotContain(t, "expected no --android-platform-build in stable_app r8 flags",
88		stableAppR8.Args["r8Flags"], "--android-platform-build")
89	android.AssertStringDoesContain(t, "expected --android-platform-build in core_platform_app r8 flags",
90		corePlatformAppR8.Args["r8Flags"], "--android-platform-build")
91}
92
93func TestR8TransitiveDeps(t *testing.T) {
94	bp := `
95		override_android_app {
96			name: "override_app",
97			base: "app",
98		}
99
100		android_app {
101			name: "app",
102			srcs: ["foo.java"],
103			libs: [
104				"lib",
105				"uses_libs_dep_import",
106			],
107			static_libs: [
108				"static_lib",
109				"repeated_dep",
110			],
111			platform_apis: true,
112		}
113
114		java_library {
115			name: "static_lib",
116			srcs: ["foo.java"],
117		}
118
119		java_library {
120			name: "lib",
121			libs: [
122				"transitive_lib",
123				"repeated_dep",
124				"prebuilt_lib",
125			],
126			static_libs: ["transitive_static_lib"],
127			srcs: ["foo.java"],
128		}
129
130		java_library {
131			name: "repeated_dep",
132			srcs: ["foo.java"],
133		}
134
135		java_library {
136			name: "transitive_static_lib",
137			srcs: ["foo.java"],
138		}
139
140		java_library {
141			name: "transitive_lib",
142			srcs: ["foo.java"],
143			libs: ["transitive_lib_2"],
144		}
145
146		java_library {
147			name: "transitive_lib_2",
148			srcs: ["foo.java"],
149		}
150
151		java_import {
152			name: "lib",
153			jars: ["lib.jar"],
154		}
155
156		java_library {
157			name: "uses_lib",
158			srcs: ["foo.java"],
159		}
160
161		java_library {
162			name: "optional_uses_lib",
163			srcs: ["foo.java"],
164		}
165
166		android_library {
167			name: "uses_libs_dep",
168			uses_libs: ["uses_lib"],
169			optional_uses_libs: ["optional_uses_lib"],
170		}
171
172		android_library_import {
173			name: "uses_libs_dep_import",
174			aars: ["aar.aar"],
175			static_libs: ["uses_libs_dep"],
176		}
177	`
178
179	testcases := []struct {
180		name      string
181		unbundled bool
182	}{
183		{
184			name:      "non-unbundled build",
185			unbundled: false,
186		},
187		{
188			name:      "unbundled build",
189			unbundled: true,
190		},
191	}
192
193	for _, tc := range testcases {
194		t.Run(tc.name, func(t *testing.T) {
195			fixturePreparer := PrepareForTestWithJavaDefaultModules
196			if tc.unbundled {
197				fixturePreparer = android.GroupFixturePreparers(
198					fixturePreparer,
199					android.FixtureModifyProductVariables(
200						func(variables android.FixtureProductVariables) {
201							variables.Unbundled_build = proptools.BoolPtr(true)
202						},
203					),
204				)
205			}
206			result := fixturePreparer.RunTestWithBp(t, bp)
207
208			getHeaderJar := func(name string) android.Path {
209				mod := result.ModuleForTests(name, "android_common")
210				return mod.Output("turbine-combined/" + name + ".jar").Output
211			}
212
213			appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
214			overrideAppR8 := result.ModuleForTests("app", "android_common_override_app").Rule("r8")
215			appHeader := getHeaderJar("app")
216			overrideAppHeader := result.ModuleForTests("app", "android_common_override_app").Output("turbine-combined/app.jar").Output
217			libHeader := getHeaderJar("lib")
218			transitiveLibHeader := getHeaderJar("transitive_lib")
219			transitiveLib2Header := getHeaderJar("transitive_lib_2")
220			staticLibHeader := getHeaderJar("static_lib")
221			transitiveStaticLibHeader := getHeaderJar("transitive_static_lib")
222			repeatedDepHeader := getHeaderJar("repeated_dep")
223			usesLibHeader := getHeaderJar("uses_lib")
224			optionalUsesLibHeader := getHeaderJar("optional_uses_lib")
225			prebuiltLibHeader := result.ModuleForTests("prebuilt_lib", "android_common").Output("combined/lib.jar").Output
226
227			for _, rule := range []android.TestingBuildParams{appR8, overrideAppR8} {
228				android.AssertStringDoesNotContain(t, "expected no app header jar in app r8 classpath",
229					rule.Args["r8Flags"], appHeader.String())
230				android.AssertStringDoesNotContain(t, "expected no override_app header jar in app r8 classpath",
231					rule.Args["r8Flags"], overrideAppHeader.String())
232				android.AssertStringDoesContain(t, "expected transitive lib header jar in app r8 classpath",
233					rule.Args["r8Flags"], transitiveLibHeader.String())
234				android.AssertStringDoesContain(t, "expected transitive lib ^2 header jar in app r8 classpath",
235					rule.Args["r8Flags"], transitiveLib2Header.String())
236				android.AssertStringDoesContain(t, "expected lib header jar in app r8 classpath",
237					rule.Args["r8Flags"], libHeader.String())
238				android.AssertStringDoesContain(t, "expected uses_lib header jar in app r8 classpath",
239					rule.Args["r8Flags"], usesLibHeader.String())
240				android.AssertStringDoesContain(t, "expected optional_uses_lib header jar in app r8 classpath",
241					rule.Args["r8Flags"], optionalUsesLibHeader.String())
242				android.AssertStringDoesNotContain(t, "expected no static_lib header jar in app r8 classpath",
243					rule.Args["r8Flags"], staticLibHeader.String())
244				android.AssertStringDoesNotContain(t, "expected no transitive static_lib header jar in app r8 classpath",
245					rule.Args["r8Flags"], transitiveStaticLibHeader.String())
246				// we shouldn't list this dep because it is already included as static_libs in the app
247				android.AssertStringDoesNotContain(t, "expected no repeated_dep header jar in app r8 classpath",
248					rule.Args["r8Flags"], repeatedDepHeader.String())
249				// skip a prebuilt transitive dep if the source is also a transitive dep
250				android.AssertStringDoesNotContain(t, "expected no prebuilt header jar in app r8 classpath",
251					rule.Args["r8Flags"], prebuiltLibHeader.String())
252				android.AssertStringDoesContain(t, "expected -ignorewarnings in app r8 flags",
253					rule.Args["r8Flags"], "-ignorewarnings")
254				android.AssertStringDoesContain(t, "expected --android-platform-build in app r8 flags",
255					rule.Args["r8Flags"], "--android-platform-build")
256			}
257		})
258	}
259}
260
261func TestR8Flags(t *testing.T) {
262	result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
263		android_app {
264			name: "app",
265			srcs: ["foo.java"],
266			platform_apis: true,
267			optimize: {
268				shrink: false,
269				optimize: false,
270				obfuscate: false,
271				ignore_warnings: false,
272			},
273		}
274	`)
275
276	app := result.ModuleForTests("app", "android_common")
277	appR8 := app.Rule("r8")
278	android.AssertStringDoesContain(t, "expected -dontshrink in app r8 flags",
279		appR8.Args["r8Flags"], "-dontshrink")
280	android.AssertStringDoesContain(t, "expected -dontoptimize in app r8 flags",
281		appR8.Args["r8Flags"], "-dontoptimize")
282	android.AssertStringDoesContain(t, "expected -dontobfuscate in app r8 flags",
283		appR8.Args["r8Flags"], "-dontobfuscate")
284	android.AssertStringDoesNotContain(t, "expected no -ignorewarnings in app r8 flags",
285		appR8.Args["r8Flags"], "-ignorewarnings")
286	android.AssertStringDoesContain(t, "expected --android-platform-build in app r8 flags",
287		appR8.Args["r8Flags"], "--android-platform-build")
288}
289
290func TestD8(t *testing.T) {
291	result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
292		java_library {
293			name: "foo",
294			srcs: ["foo.java"],
295			libs: ["lib"],
296			static_libs: ["static_lib"],
297			installable: true,
298		}
299
300		java_library {
301			name: "lib",
302			srcs: ["foo.java"],
303		}
304
305		java_library {
306			name: "static_lib",
307			srcs: ["foo.java"],
308		}
309	`)
310
311	foo := result.ModuleForTests("foo", "android_common")
312	lib := result.ModuleForTests("lib", "android_common")
313	staticLib := result.ModuleForTests("static_lib", "android_common")
314
315	fooJavac := foo.Rule("javac")
316	fooD8 := foo.Rule("d8")
317	libHeader := lib.Output("turbine-combined/lib.jar").Output
318	staticLibHeader := staticLib.Output("turbine-combined/static_lib.jar").Output
319
320	android.AssertStringDoesContain(t, "expected lib header jar in foo javac classpath",
321		fooJavac.Args["classpath"], libHeader.String())
322	android.AssertStringDoesContain(t, "expected static_lib header jar in foo javac classpath",
323		fooJavac.Args["classpath"], staticLibHeader.String())
324
325	android.AssertStringDoesContain(t, "expected lib header jar in foo d8 classpath",
326		fooD8.Args["d8Flags"], libHeader.String())
327	android.AssertStringDoesNotContain(t, "expected no  static_lib header jar in foo javac classpath",
328		fooD8.Args["d8Flags"], staticLibHeader.String())
329}
330
331func TestProguardFlagsInheritanceStatic(t *testing.T) {
332	result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
333		android_app {
334			name: "app",
335			static_libs: [
336				"primary_android_lib",
337				"primary_lib",
338			],
339			platform_apis: true,
340		}
341
342		java_library {
343			name: "primary_lib",
344			optimize: {
345				proguard_flags_files: ["primary.flags"],
346			},
347		}
348
349		android_library {
350			name: "primary_android_lib",
351			static_libs: ["secondary_lib"],
352			optimize: {
353				proguard_flags_files: ["primary_android.flags"],
354			},
355		}
356
357		java_library {
358			name: "secondary_lib",
359			static_libs: ["tertiary_lib"],
360			optimize: {
361				proguard_flags_files: ["secondary.flags"],
362			},
363		}
364
365		java_library {
366			name: "tertiary_lib",
367			optimize: {
368				proguard_flags_files: ["tertiary.flags"],
369			},
370		}
371	`)
372
373	app := result.ModuleForTests("app", "android_common")
374	appR8 := app.Rule("r8")
375	android.AssertStringDoesContain(t, "expected primary_lib's proguard flags from direct dep",
376		appR8.Args["r8Flags"], "primary.flags")
377	android.AssertStringDoesContain(t, "expected primary_android_lib's proguard flags from direct dep",
378		appR8.Args["r8Flags"], "primary_android.flags")
379	android.AssertStringDoesContain(t, "expected secondary_lib's proguard flags from inherited dep",
380		appR8.Args["r8Flags"], "secondary.flags")
381	android.AssertStringDoesContain(t, "expected tertiary_lib's proguard flags from inherited dep",
382		appR8.Args["r8Flags"], "tertiary.flags")
383}
384
385func TestProguardFlagsInheritance(t *testing.T) {
386	directDepFlagsFileName := "direct_dep.flags"
387	transitiveDepFlagsFileName := "transitive_dep.flags"
388
389	topLevelModules := []struct {
390		name       string
391		definition string
392	}{
393		{
394			name: "android_app",
395			definition: `
396				android_app {
397					name: "app",
398					static_libs: ["androidlib"], // this must be static_libs to initate dexing
399					platform_apis: true,
400				}
401			`,
402		},
403		{
404			name: "android_library",
405			definition: `
406				android_library {
407					name: "app",
408					static_libs: ["androidlib"], // this must be static_libs to initate dexing
409					installable: true,
410					optimize: {
411						enabled: true,
412						shrink: true,
413					},
414				}
415			`,
416		},
417		{
418			name: "java_library",
419			definition: `
420				java_library {
421					name: "app",
422					static_libs: ["androidlib"], // this must be static_libs to initate dexing
423					srcs: ["Foo.java"],
424					installable: true,
425					optimize: {
426						enabled: true,
427						shrink: true,
428					},
429				}
430			`,
431		},
432	}
433
434	bp := `
435		android_library {
436			name: "androidlib",
437			static_libs: ["app_dep"],
438		}
439
440		java_library {
441			name: "app_dep",
442			%s: ["dep"],
443		}
444
445		java_library {
446			name: "dep",
447			%s: ["transitive_dep"],
448			optimize: {
449				proguard_flags_files: ["direct_dep.flags"],
450				export_proguard_flags_files: %v,
451			},
452		}
453
454		java_library {
455			name: "transitive_dep",
456			optimize: {
457				proguard_flags_files: ["transitive_dep.flags"],
458				export_proguard_flags_files: %v,
459			},
460		}
461	`
462
463	testcases := []struct {
464		name                           string
465		depType                        string
466		depExportsFlagsFiles           bool
467		transitiveDepType              string
468		transitiveDepExportsFlagsFiles bool
469		expectedFlagsFiles             []string
470	}{
471		{
472			name:                           "libs_export_libs_export",
473			depType:                        "libs",
474			depExportsFlagsFiles:           true,
475			transitiveDepType:              "libs",
476			transitiveDepExportsFlagsFiles: true,
477			expectedFlagsFiles:             []string{directDepFlagsFileName, transitiveDepFlagsFileName},
478		},
479		{
480			name:                           "static_export_libs_export",
481			depType:                        "static_libs",
482			depExportsFlagsFiles:           true,
483			transitiveDepType:              "libs",
484			transitiveDepExportsFlagsFiles: true,
485			expectedFlagsFiles:             []string{directDepFlagsFileName, transitiveDepFlagsFileName},
486		},
487		{
488			name:                           "libs_no-export_static_export",
489			depType:                        "libs",
490			depExportsFlagsFiles:           false,
491			transitiveDepType:              "static_libs",
492			transitiveDepExportsFlagsFiles: true,
493			expectedFlagsFiles:             []string{transitiveDepFlagsFileName},
494		},
495		{
496			name:                           "static_no-export_static_export",
497			depType:                        "static_libs",
498			depExportsFlagsFiles:           false,
499			transitiveDepType:              "static_libs",
500			transitiveDepExportsFlagsFiles: true,
501			expectedFlagsFiles:             []string{directDepFlagsFileName, transitiveDepFlagsFileName},
502		},
503		{
504			name:                           "libs_export_libs_no-export",
505			depType:                        "libs",
506			depExportsFlagsFiles:           true,
507			transitiveDepType:              "libs",
508			transitiveDepExportsFlagsFiles: false,
509			expectedFlagsFiles:             []string{directDepFlagsFileName},
510		},
511		{
512			name:                           "static_export_libs_no-export",
513			depType:                        "static_libs",
514			depExportsFlagsFiles:           true,
515			transitiveDepType:              "libs",
516			transitiveDepExportsFlagsFiles: false,
517			expectedFlagsFiles:             []string{directDepFlagsFileName},
518		},
519		{
520			name:                           "libs_no-export_static_no-export",
521			depType:                        "libs",
522			depExportsFlagsFiles:           false,
523			transitiveDepType:              "static_libs",
524			transitiveDepExportsFlagsFiles: false,
525			expectedFlagsFiles:             []string{},
526		},
527		{
528			name:                           "static_no-export_static_no-export",
529			depType:                        "static_libs",
530			depExportsFlagsFiles:           false,
531			transitiveDepType:              "static_libs",
532			transitiveDepExportsFlagsFiles: false,
533			expectedFlagsFiles:             []string{directDepFlagsFileName, transitiveDepFlagsFileName},
534		},
535		{
536			name:                           "libs_no-export_libs_export",
537			depType:                        "libs",
538			depExportsFlagsFiles:           false,
539			transitiveDepType:              "libs",
540			transitiveDepExportsFlagsFiles: true,
541			expectedFlagsFiles:             []string{transitiveDepFlagsFileName},
542		},
543		{
544			name:                           "static_no-export_libs_export",
545			depType:                        "static_libs",
546			depExportsFlagsFiles:           false,
547			transitiveDepType:              "libs",
548			transitiveDepExportsFlagsFiles: true,
549			expectedFlagsFiles:             []string{directDepFlagsFileName, transitiveDepFlagsFileName},
550		},
551		{
552			name:                           "libs_export_static_export",
553			depType:                        "libs",
554			depExportsFlagsFiles:           true,
555			transitiveDepType:              "static_libs",
556			transitiveDepExportsFlagsFiles: true,
557			expectedFlagsFiles:             []string{directDepFlagsFileName, transitiveDepFlagsFileName},
558		},
559		{
560			name:                           "static_export_static_export",
561			depType:                        "static_libs",
562			depExportsFlagsFiles:           true,
563			transitiveDepType:              "static_libs",
564			transitiveDepExportsFlagsFiles: true,
565			expectedFlagsFiles:             []string{directDepFlagsFileName, transitiveDepFlagsFileName},
566		},
567		{
568			name:                           "libs_no-export_libs_no-export",
569			depType:                        "libs",
570			depExportsFlagsFiles:           false,
571			transitiveDepType:              "libs",
572			transitiveDepExportsFlagsFiles: false,
573			expectedFlagsFiles:             []string{},
574		},
575		{
576			name:                           "static_no-export_libs_no-export",
577			depType:                        "static_libs",
578			depExportsFlagsFiles:           false,
579			transitiveDepType:              "libs",
580			transitiveDepExportsFlagsFiles: false,
581			expectedFlagsFiles:             []string{directDepFlagsFileName},
582		},
583		{
584			name:                           "libs_export_static_no-export",
585			depType:                        "libs",
586			depExportsFlagsFiles:           true,
587			transitiveDepType:              "static_libs",
588			transitiveDepExportsFlagsFiles: false,
589			expectedFlagsFiles:             []string{directDepFlagsFileName, transitiveDepFlagsFileName},
590		},
591		{
592			name:                           "static_export_static_no-export",
593			depType:                        "static_libs",
594			depExportsFlagsFiles:           true,
595			transitiveDepType:              "static_libs",
596			transitiveDepExportsFlagsFiles: false,
597			expectedFlagsFiles:             []string{directDepFlagsFileName, transitiveDepFlagsFileName},
598		},
599	}
600
601	for _, topLevelModuleDef := range topLevelModules {
602		for _, tc := range testcases {
603			t.Run(topLevelModuleDef.name+"-"+tc.name, func(t *testing.T) {
604				result := android.GroupFixturePreparers(
605					PrepareForTestWithJavaDefaultModules,
606					android.FixtureMergeMockFs(android.MockFS{
607						directDepFlagsFileName:     nil,
608						transitiveDepFlagsFileName: nil,
609					}),
610				).RunTestWithBp(t,
611					topLevelModuleDef.definition+
612						fmt.Sprintf(
613							bp,
614							tc.depType,
615							tc.transitiveDepType,
616							tc.depExportsFlagsFiles,
617							tc.transitiveDepExportsFlagsFiles,
618						),
619				)
620				appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
621
622				shouldHaveDepFlags := android.InList(directDepFlagsFileName, tc.expectedFlagsFiles)
623				if shouldHaveDepFlags {
624					android.AssertStringDoesContain(t, "expected deps's proguard flags",
625						appR8.Args["r8Flags"], directDepFlagsFileName)
626				} else {
627					android.AssertStringDoesNotContain(t, "app did not expect deps's proguard flags",
628						appR8.Args["r8Flags"], directDepFlagsFileName)
629				}
630
631				shouldHaveTransitiveDepFlags := android.InList(transitiveDepFlagsFileName, tc.expectedFlagsFiles)
632				if shouldHaveTransitiveDepFlags {
633					android.AssertStringDoesContain(t, "expected transitive deps's proguard flags",
634						appR8.Args["r8Flags"], transitiveDepFlagsFileName)
635				} else {
636					android.AssertStringDoesNotContain(t, "app did not expect transitive deps's proguard flags",
637						appR8.Args["r8Flags"], transitiveDepFlagsFileName)
638				}
639			})
640		}
641	}
642}
643
644func TestProguardFlagsInheritanceAppImport(t *testing.T) {
645	bp := `
646		android_app {
647			name: "app",
648			static_libs: ["aarimport"], // this must be static_libs to initate dexing
649			platform_apis: true,
650		}
651
652		android_library_import {
653			name: "aarimport",
654			aars: ["import.aar"],
655		}
656	`
657	result := android.GroupFixturePreparers(
658		PrepareForTestWithJavaDefaultModules,
659	).RunTestWithBp(t, bp)
660
661	appR8 := result.ModuleForTests("app", "android_common").Rule("r8")
662	android.AssertStringDoesContain(t, "expected aarimports's proguard flags",
663		appR8.Args["r8Flags"], "proguard.txt")
664}
665
666func TestR8FlagsArtProfile(t *testing.T) {
667	result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
668		android_app {
669			name: "app",
670			srcs: ["foo.java"],
671			platform_apis: true,
672			dex_preopt: {
673				profile_guided: true,
674				profile: "profile.txt.prof",
675				enable_profile_rewriting: true,
676			},
677		}
678	`)
679
680	app := result.ModuleForTests("app", "android_common")
681	appR8 := app.Rule("r8")
682	android.AssertStringDoesContain(t, "expected --art-profile in app r8 flags",
683		appR8.Args["r8Flags"], "--art-profile")
684
685	appDexpreopt := app.Rule("dexpreopt")
686	android.AssertStringDoesContain(t,
687		"expected --art-profile output to be used to create .prof binary",
688		appDexpreopt.RuleParams.Command,
689		"--create-profile-from=out/soong/.intermediates/app/android_common/profile.prof.txt --output-profile-type=app",
690	)
691}
692
693// This test checks that users explicitly set `enable_profile_rewriting` to true when the following are true
694// 1. optimize or obfuscate is enabled AND
695// 2. dex_preopt.profile_guided is enabled
696//
697// The rewritten profile should be used since the dex signatures in the checked-in profile will not match the optimized binary.
698func TestEnableProfileRewritingIsRequiredForOptimizedApps(t *testing.T) {
699	testJavaError(t,
700		"Enable_profile_rewriting must be true when profile_guided dexpreopt and R8 optimization/obfuscation is turned on",
701		`
702android_app {
703	name: "app",
704	srcs: ["foo.java"],
705	platform_apis: true,
706	dex_preopt: {
707		profile_guided: true,
708		profile: "profile.txt.prof",
709		// enable_profile_rewriting is not set, this is an error
710	},
711	optimize: {
712		optimize: true,
713	}
714}`)
715}
716