Merge "Prebuilt APEXes are recoreded in apexkeys.txt" into qt-dev
diff --git a/android/module.go b/android/module.go
index 201c27a..11e9e91 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1034,6 +1034,39 @@
 	return aModule
 }
 
+func (a *androidModuleContext) getDirectDepInternal(name string, tag blueprint.DependencyTag) (blueprint.Module, blueprint.DependencyTag) {
+	type dep struct {
+		mod blueprint.Module
+		tag blueprint.DependencyTag
+	}
+	var deps []dep
+	a.VisitDirectDepsBlueprint(func(m blueprint.Module) {
+		if aModule, _ := m.(Module); aModule != nil && aModule.base().BaseModuleName() == name {
+			returnedTag := a.ModuleContext.OtherModuleDependencyTag(aModule)
+			if tag == nil || returnedTag == tag {
+				deps = append(deps, dep{aModule, returnedTag})
+			}
+		}
+	})
+	if len(deps) == 1 {
+		return deps[0].mod, deps[0].tag
+	} else if len(deps) >= 2 {
+		panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
+			name, a.ModuleName()))
+	} else {
+		return nil, nil
+	}
+}
+
+func (a *androidModuleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module {
+	m, _ := a.getDirectDepInternal(name, tag)
+	return m
+}
+
+func (a *androidModuleContext) GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag) {
+	return a.getDirectDepInternal(name, nil)
+}
+
 func (a *androidModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
 	a.ModuleContext.VisitDirectDeps(visit)
 }
diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go
index 319c15d..e182641 100644
--- a/android/prebuilt_test.go
+++ b/android/prebuilt_test.go
@@ -41,7 +41,7 @@
 			prebuilt {
 				name: "bar",
 				prefer: false,
-				srcs: ["prebuilt"],
+				srcs: ["prebuilt_file"],
 			}`,
 		prebuilt: true,
 	},
@@ -51,7 +51,7 @@
 			prebuilt {
 				name: "bar",
 				prefer: true,
-				srcs: ["prebuilt"],
+				srcs: ["prebuilt_file"],
 			}`,
 		prebuilt: true,
 	},
@@ -65,7 +65,7 @@
 			prebuilt {
 				name: "bar",
 				prefer: false,
-				srcs: ["prebuilt"],
+				srcs: ["prebuilt_file"],
 			}`,
 		prebuilt: false,
 	},
@@ -79,7 +79,7 @@
 			prebuilt {
 				name: "bar",
 				prefer: true,
-				srcs: ["prebuilt"],
+				srcs: ["prebuilt_file"],
 			}`,
 		prebuilt: true,
 	},
@@ -114,6 +114,7 @@
 		modules: `
 			filegroup {
 				name: "fg",
+				srcs: ["prebuilt_file"],
 			}
 			prebuilt {
 				name: "bar",
@@ -143,10 +144,12 @@
 			ctx.RegisterModuleType("source", ModuleFactoryAdaptor(newSourceModule))
 			ctx.Register()
 			ctx.MockFileSystem(map[string][]byte{
+				"prebuilt_file": nil,
+				"source_file":   nil,
 				"Blueprints": []byte(`
 					source {
 						name: "foo",
-						deps: ["bar"],
+						deps: [":bar"],
 					}
 					` + test.modules),
 			})
@@ -171,21 +174,45 @@
 				}
 			})
 
+			deps := foo.Module().(*sourceModule).deps
+			if deps == nil || len(deps) != 1 {
+				t.Errorf("deps does not have single path, but is %v", deps)
+			}
+			var usingSourceFile, usingPrebuiltFile bool
+			if deps[0].String() == "source_file" {
+				usingSourceFile = true
+			}
+			if deps[0].String() == "prebuilt_file" {
+				usingPrebuiltFile = true
+			}
+
 			if test.prebuilt {
 				if !dependsOnPrebuiltModule {
 					t.Errorf("doesn't depend on prebuilt module")
 				}
+				if !usingPrebuiltFile {
+					t.Errorf("doesn't use prebuilt_file")
+				}
 
 				if dependsOnSourceModule {
 					t.Errorf("depends on source module")
 				}
+				if usingSourceFile {
+					t.Errorf("using source_file")
+				}
 			} else {
 				if dependsOnPrebuiltModule {
 					t.Errorf("depends on prebuilt module")
 				}
+				if usingPrebuiltFile {
+					t.Errorf("using prebuilt_file")
+				}
 
 				if !dependsOnSourceModule {
-					t.Errorf("doens't depend on source module")
+					t.Errorf("doesn't depend on source module")
+				}
+				if !usingSourceFile {
+					t.Errorf("doesn't use source_file")
 				}
 			}
 		})
@@ -198,6 +225,7 @@
 	properties struct {
 		Srcs []string `android:"path"`
 	}
+	src Path
 }
 
 func newPrebuiltModule() Module {
@@ -212,19 +240,28 @@
 	return p.prebuilt.Name(p.ModuleBase.Name())
 }
 
-func (p *prebuiltModule) GenerateAndroidBuildActions(ModuleContext) {
+func (p *prebuiltModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+	if len(p.properties.Srcs) >= 1 {
+		p.src = p.prebuilt.SingleSourcePath(ctx)
+	}
 }
 
 func (p *prebuiltModule) Prebuilt() *Prebuilt {
 	return &p.prebuilt
 }
 
+func (p *prebuiltModule) Srcs() Paths {
+	return Paths{p.src}
+}
+
 type sourceModule struct {
 	ModuleBase
 	properties struct {
-		Deps []string
+		Deps []string `android:"path"`
 	}
 	dependsOnSourceModule, dependsOnPrebuiltModule bool
+	deps                                           Paths
+	src                                            Path
 }
 
 func newSourceModule() Module {
@@ -235,10 +272,15 @@
 }
 
 func (s *sourceModule) DepsMutator(ctx BottomUpMutatorContext) {
-	for _, d := range s.properties.Deps {
-		ctx.AddDependency(ctx.Module(), nil, d)
-	}
+	// s.properties.Deps are annotated with android:path, so they are
+	// automatically added to the dependency by pathDeps mutator
 }
 
 func (s *sourceModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+	s.deps = PathsForModuleSrc(ctx, s.properties.Deps)
+	s.src = PathForModuleSrc(ctx, "source_file")
+}
+
+func (s *sourceModule) Srcs() Paths {
+	return Paths{s.src}
 }
diff --git a/apex/apex.go b/apex/apex.go
index 178927d..fa4cb48 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -977,6 +977,17 @@
 			optFlags = append(optFlags, "--android_manifest "+androidManifestFile.String())
 		}
 
+		targetSdkVersion := ctx.Config().DefaultAppTargetSdk()
+		if targetSdkVersion == ctx.Config().PlatformSdkCodename() &&
+			ctx.Config().UnbundledBuild() &&
+			!ctx.Config().UnbundledBuildUsePrebuiltSdks() &&
+			ctx.Config().IsEnvTrue("UNBUNDLED_BUILD_TARGET_SDK_WITH_API_FINGERPRINT") {
+			apiFingerprint := java.ApiFingerprintPath(ctx)
+			targetSdkVersion += fmt.Sprintf(".$$(cat %s)", apiFingerprint.String())
+			implicitInputs = append(implicitInputs, apiFingerprint)
+		}
+		optFlags = append(optFlags, "--target_sdk_version "+targetSdkVersion)
+
 		ctx.Build(pctx, android.BuildParams{
 			Rule:        apexRule,
 			Implicits:   implicitInputs,
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 3c80376..c771ae4 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -171,6 +171,7 @@
 		"testkey2.pem":                         nil,
 		"myapex-arm64.apex":                    nil,
 		"myapex-arm.apex":                      nil,
+		"frameworks/base/api/current.txt":      nil,
 	})
 	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
 	android.FailIfErrored(t, errs)
@@ -190,6 +191,8 @@
 	config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current")
 	config.TestProductVariables.DefaultAppCertificate = proptools.StringPtr("vendor/foo/devkeys/test")
 	config.TestProductVariables.CertificateOverrides = []string{"myapex_keytest:myapex.certificate.override"}
+	config.TestProductVariables.Platform_sdk_codename = proptools.StringPtr("Q")
+	config.TestProductVariables.Platform_sdk_final = proptools.BoolPtr(false)
 	return
 }
 
diff --git a/java/android_manifest.go b/java/android_manifest.go
index 39cf471..8dc3b47 100644
--- a/java/android_manifest.go
+++ b/java/android_manifest.go
@@ -74,7 +74,7 @@
 		ctx.Config().UnbundledBuild() &&
 		!ctx.Config().UnbundledBuildUsePrebuiltSdks() &&
 		ctx.Config().IsEnvTrue("UNBUNDLED_BUILD_TARGET_SDK_WITH_API_FINGERPRINT") {
-		apiFingerprint := apiFingerprintPath(ctx)
+		apiFingerprint := ApiFingerprintPath(ctx)
 		targetSdkVersion += fmt.Sprintf(".$$(cat %s)", apiFingerprint.String())
 		deps = append(deps, apiFingerprint)
 	}
diff --git a/java/app.go b/java/app.go
index ab623e2..da8024f 100644
--- a/java/app.go
+++ b/java/app.go
@@ -438,7 +438,7 @@
 func AndroidAppFactory() android.Module {
 	module := &AndroidApp{}
 
-	module.Module.deviceProperties.Optimize.Enabled = proptools.BoolPtr(true)
+	module.Module.deviceProperties.Optimize.EnabledByDefault = true
 	module.Module.deviceProperties.Optimize.Shrink = proptools.BoolPtr(true)
 
 	module.Module.properties.Instrument = true
@@ -508,7 +508,7 @@
 func AndroidTestFactory() android.Module {
 	module := &AndroidTest{}
 
-	module.Module.deviceProperties.Optimize.Enabled = proptools.BoolPtr(true)
+	module.Module.deviceProperties.Optimize.EnabledByDefault = true
 
 	module.Module.properties.Instrument = true
 	module.Module.properties.Installable = proptools.BoolPtr(true)
@@ -550,7 +550,7 @@
 func AndroidTestHelperAppFactory() android.Module {
 	module := &AndroidTestHelperApp{}
 
-	module.Module.deviceProperties.Optimize.Enabled = proptools.BoolPtr(true)
+	module.Module.deviceProperties.Optimize.EnabledByDefault = true
 
 	module.Module.properties.Installable = proptools.BoolPtr(true)
 	module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
diff --git a/java/dex.go b/java/dex.go
index 987129e..c8a4fa8 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -171,7 +171,7 @@
 func (j *Module) compileDex(ctx android.ModuleContext, flags javaBuilderFlags,
 	classesJar android.Path, jarName string) android.ModuleOutPath {
 
-	useR8 := Bool(j.deviceProperties.Optimize.Enabled)
+	useR8 := j.deviceProperties.EffectiveOptimizeEnabled()
 
 	// Compile classes.jar into classes.dex and then javalib.jar
 	javalibJar := android.PathForModuleOut(ctx, "dex", jarName)
diff --git a/java/java.go b/java/java.go
index 793e40b..b0ad8c2 100644
--- a/java/java.go
+++ b/java/java.go
@@ -228,6 +228,8 @@
 		// If false, disable all optimization.  Defaults to true for android_app and android_test
 		// modules, false for java_library and java_test modules.
 		Enabled *bool
+		// True if the module containing this has it set by default.
+		EnabledByDefault bool `blueprint:"mutated"`
 
 		// If true, optimize for size by removing unused code.  Defaults to true for apps,
 		// false for libraries and tests.
@@ -257,6 +259,10 @@
 	IsSDKLibrary  bool `blueprint:"mutated"`
 }
 
+func (me *CompilerDeviceProperties) EffectiveOptimizeEnabled() bool {
+	return BoolDefault(me.Optimize.Enabled, me.Optimize.EnabledByDefault)
+}
+
 // Module contains the properties and members used by all java module types
 type Module struct {
 	android.ModuleBase
@@ -460,7 +466,7 @@
 			} else if sdkDep.useModule {
 				ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
 				ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
-				if Bool(j.deviceProperties.Optimize.Enabled) {
+				if j.deviceProperties.EffectiveOptimizeEnabled() {
 					ctx.AddVariationDependencies(nil, proguardRaiseTag, config.DefaultBootclasspathLibraries...)
 					ctx.AddVariationDependencies(nil, proguardRaiseTag, config.DefaultLibraries...)
 				}
diff --git a/java/java_test.go b/java/java_test.go
index c148807..a5c0aa9 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -368,6 +368,7 @@
 			srcs: ["a.java"],
 			libs: ["bar"],
 			static_libs: ["baz"],
+			optimize: {enabled: false},
 		}
 
 		java_library {
@@ -384,6 +385,22 @@
 			name: "baz",
 			srcs: ["c.java"],
 		}
+
+		android_test {
+			name: "atestOptimize",
+			defaults: ["defaults"],
+			optimize: {enabled: true},
+		}
+
+		android_test {
+			name: "atestNoOptimize",
+			defaults: ["defaults"],
+		}
+
+		android_test {
+			name: "atestDefault",
+			srcs: ["a.java"],
+		}
 		`)
 
 	javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
@@ -402,6 +419,21 @@
 	if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != baz {
 		t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz)
 	}
+
+	atestOptimize := ctx.ModuleForTests("atestOptimize", "android_common").MaybeRule("r8")
+	if atestOptimize.Output == nil {
+		t.Errorf("atestOptimize should optimize APK")
+	}
+
+	atestNoOptimize := ctx.ModuleForTests("atestNoOptimize", "android_common").MaybeRule("d8")
+	if atestNoOptimize.Output == nil {
+		t.Errorf("atestNoOptimize should not optimize APK")
+	}
+
+	atestDefault := ctx.ModuleForTests("atestDefault", "android_common").MaybeRule("r8")
+	if atestDefault.Output == nil {
+		t.Errorf("atestDefault should optimize APK")
+	}
 }
 
 func TestResources(t *testing.T) {
diff --git a/java/sdk.go b/java/sdk.go
index 36010b6..e93f8fb 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -316,7 +316,7 @@
 
 // Create api_fingerprint.txt
 func createAPIFingerprint(ctx android.SingletonContext) {
-	out := apiFingerprintPath(ctx)
+	out := ApiFingerprintPath(ctx)
 
 	rule := android.NewRuleBuilder()
 
@@ -359,7 +359,7 @@
 	rule.Build(pctx, ctx, "api_fingerprint", "generate api_fingerprint.txt")
 }
 
-func apiFingerprintPath(ctx android.PathContext) android.OutputPath {
+func ApiFingerprintPath(ctx android.PathContext) android.OutputPath {
 	return ctx.Config().Once(apiFingerprintPathKey, func() interface{} {
 		return android.PathForOutput(ctx, "api_fingerprint.txt")
 	}).(android.OutputPath)
@@ -371,5 +371,5 @@
 	}
 
 	ctx.Strict("FRAMEWORK_AIDL", sdkFrameworkAidlPath(ctx).String())
-	ctx.Strict("API_FINGERPRINT", apiFingerprintPath(ctx).String())
+	ctx.Strict("API_FINGERPRINT", ApiFingerprintPath(ctx).String())
 }