Make RuleBuilder methods take Paths

There are no more Make paths being used in Soong now that
dexpreopting and hiddenapi are in Soong. Use the Path types
in the inputs to RuleBuilder, and fix all users of RuleBuilder.

Test: all soong tests
Test: m checkbuild
Change-Id: I886f803d9a3419a43b2cae412537645f94c5dfbf
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 0a56529..b53e9c4 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -86,18 +86,28 @@
 }
 
 var dexpreoptGlobalConfigKey = android.NewOnceKey("DexpreoptGlobalConfig")
+var dexpreoptTestGlobalConfigKey = android.NewOnceKey("TestDexpreoptGlobalConfig")
+
+func setDexpreoptGlobalConfig(config android.Config, globalConfig dexpreopt.GlobalConfig) {
+	config.Once(dexpreoptTestGlobalConfigKey, func() interface{} { return globalConfig })
+}
 
 func dexpreoptGlobalConfig(ctx android.PathContext) dexpreopt.GlobalConfig {
 	return ctx.Config().Once(dexpreoptGlobalConfigKey, func() interface{} {
 		if f := ctx.Config().DexpreoptGlobalConfig(); f != "" {
 			ctx.AddNinjaFileDeps(f)
-			globalConfig, err := dexpreopt.LoadGlobalConfig(f)
+			globalConfig, err := dexpreopt.LoadGlobalConfig(ctx, f)
 			if err != nil {
 				panic(err)
 			}
 			return globalConfig
 		}
-		return dexpreopt.GlobalConfig{}
+
+		// No global config filename set, see if there is a test config set
+		return ctx.Config().Once(dexpreoptTestGlobalConfigKey, func() interface{} {
+			// Nope, return an empty config
+			return dexpreopt.GlobalConfig{}
+		})
 	}).(dexpreopt.GlobalConfig)
 }
 
@@ -131,17 +141,15 @@
 		archs = archs[:1]
 	}
 
-	var images []string
+	var images android.Paths
 	for _, arch := range archs {
-		images = append(images, info.images[arch].String())
+		images = append(images, info.images[arch])
 	}
 
 	dexLocation := android.InstallPathToOnDevicePath(ctx, d.installPath)
 
 	strippedDexJarFile := android.PathForModuleOut(ctx, "dexpreopt", dexJarFile.Base())
 
-	deps := android.Paths{dexJarFile}
-
 	var profileClassListing android.OptionalPath
 	profileIsTextListing := false
 	if BoolDefault(d.dexpreoptProperties.Dex_preopt.Profile_guided, true) {
@@ -157,20 +165,16 @@
 		}
 	}
 
-	if profileClassListing.Valid() {
-		deps = append(deps, profileClassListing.Path())
-	}
-
 	dexpreoptConfig := dexpreopt.ModuleConfig{
 		Name:            ctx.ModuleName(),
 		DexLocation:     dexLocation,
-		BuildPath:       android.PathForModuleOut(ctx, "dexpreopt", ctx.ModuleName()+".jar").String(),
-		DexPath:         dexJarFile.String(),
+		BuildPath:       android.PathForModuleOut(ctx, "dexpreopt", ctx.ModuleName()+".jar").OutputPath,
+		DexPath:         dexJarFile,
 		UncompressedDex: d.uncompressedDex,
 		HasApkLibraries: false,
 		PreoptFlags:     nil,
 
-		ProfileClassListing:  profileClassListing.String(),
+		ProfileClassListing:  profileClassListing,
 		ProfileIsTextListing: profileIsTextListing,
 
 		EnforceUsesLibraries:  false,
@@ -181,7 +185,7 @@
 		Archs:           archs,
 		DexPreoptImages: images,
 
-		PreoptBootClassPathDexFiles:     info.preoptBootDex.Strings(),
+		PreoptBootClassPathDexFiles:     info.preoptBootDex.Paths(),
 		PreoptBootClassPathDexLocations: info.preoptBootLocations,
 
 		PreoptExtractedApk: false,
@@ -190,11 +194,11 @@
 		ForceCreateAppImage: BoolDefault(d.dexpreoptProperties.Dex_preopt.App_image, false),
 
 		NoStripping:     Bool(d.dexpreoptProperties.Dex_preopt.No_stripping),
-		StripInputPath:  dexJarFile.String(),
-		StripOutputPath: strippedDexJarFile.String(),
+		StripInputPath:  dexJarFile,
+		StripOutputPath: strippedDexJarFile.OutputPath,
 	}
 
-	dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(info.global, dexpreoptConfig)
+	dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(ctx, info.global, dexpreoptConfig)
 	if err != nil {
 		ctx.ModuleErrorf("error generating dexpreopt rule: %s", err.Error())
 		return dexJarFile
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 8853428..bb88d32 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -259,7 +259,7 @@
 	symbolsFile := symbolsDir.Join(ctx, "boot.oat")
 	outputDir := info.dir.Join(ctx, "system/framework", arch.String())
 	outputPath := info.images[arch]
-	oatLocation := pathtools.ReplaceExtension(dexpreopt.PathToLocation(outputPath.String(), arch), "oat")
+	oatLocation := pathtools.ReplaceExtension(dexpreopt.PathToLocation(outputPath, arch), "oat")
 
 	rule := android.NewRuleBuilder()
 	rule.MissingDeps(missingDeps)
@@ -289,31 +289,31 @@
 
 	cmd.Tool(info.global.Tools.Dex2oat).
 		Flag("--avoid-storing-invocation").
-		FlagWithOutput("--write-invocation-to=", invocationPath.String()).ImplicitOutput(invocationPath.String()).
+		FlagWithOutput("--write-invocation-to=", invocationPath).ImplicitOutput(invocationPath).
 		Flag("--runtime-arg").FlagWithArg("-Xms", info.global.Dex2oatImageXms).
 		Flag("--runtime-arg").FlagWithArg("-Xmx", info.global.Dex2oatImageXmx)
 
-	if profile == nil {
-		cmd.FlagWithArg("--image-classes=", info.global.PreloadedClasses)
-	} else {
+	if profile != nil {
 		cmd.FlagWithArg("--compiler-filter=", "speed-profile")
-		cmd.FlagWithInput("--profile-file=", profile.String())
+		cmd.FlagWithInput("--profile-file=", profile)
+	} else if info.global.PreloadedClasses.Valid() {
+		cmd.FlagWithInput("--image-classes=", info.global.PreloadedClasses.Path())
 	}
 
-	if info.global.DirtyImageObjects != "" {
-		cmd.FlagWithArg("--dirty-image-objects=", info.global.DirtyImageObjects)
+	if info.global.DirtyImageObjects.Valid() {
+		cmd.FlagWithInput("--dirty-image-objects=", info.global.DirtyImageObjects.Path())
 	}
 
 	cmd.
-		FlagForEachInput("--dex-file=", info.preoptBootDex.Strings()).
+		FlagForEachInput("--dex-file=", info.preoptBootDex.Paths()).
 		FlagForEachArg("--dex-location=", info.preoptBootLocations).
 		Flag("--generate-debug-info").
 		Flag("--generate-build-id").
-		FlagWithArg("--oat-symbols=", symbolsFile.String()).
+		FlagWithOutput("--oat-symbols=", symbolsFile).
 		Flag("--strip").
-		FlagWithOutput("--oat-file=", outputPath.ReplaceExtension(ctx, "oat").String()).
+		FlagWithOutput("--oat-file=", outputPath.ReplaceExtension(ctx, "oat")).
 		FlagWithArg("--oat-location=", oatLocation).
-		FlagWithOutput("--image=", outputPath.String()).
+		FlagWithOutput("--image=", outputPath).
 		FlagWithArg("--base=", ctx.Config().LibartImgDeviceBaseAddress()).
 		FlagWithArg("--instruction-set=", arch.String()).
 		FlagWithArg("--instruction-set-variant=", info.global.CpuVariant[arch]).
@@ -358,21 +358,21 @@
 		extraFiles = append(extraFiles, art, oat, vdex, unstrippedOat)
 
 		// Install the .oat and .art files.
-		rule.Install(art.String(), filepath.Join(installDir, art.Base()))
-		rule.Install(oat.String(), filepath.Join(installDir, oat.Base()))
+		rule.Install(art, filepath.Join(installDir, art.Base()))
+		rule.Install(oat, filepath.Join(installDir, oat.Base()))
 
 		// The vdex files are identical between architectures, install them to a shared location.  The Make rules will
 		// only use the install rules for one architecture, and will create symlinks into the architecture-specific
 		// directories.
 		vdexInstalls = append(vdexInstalls,
-			android.RuleBuilderInstall{vdex.String(), filepath.Join(vdexInstallDir, vdex.Base())})
+			android.RuleBuilderInstall{vdex, filepath.Join(vdexInstallDir, vdex.Base())})
 
 		// Install the unstripped oat files.  The Make rules will put these in $(TARGET_OUT_UNSTRIPPED)
 		unstrippedInstalls = append(unstrippedInstalls,
-			android.RuleBuilderInstall{unstrippedOat.String(), filepath.Join(installDir, unstrippedOat.Base())})
+			android.RuleBuilderInstall{unstrippedOat, filepath.Join(installDir, unstrippedOat.Base())})
 	}
 
-	cmd.ImplicitOutputs(extraFiles.Strings())
+	cmd.ImplicitOutputs(extraFiles)
 
 	rule.Build(pctx, ctx, "bootJarsDexpreopt_"+arch.String(), "dexpreopt boot jars "+arch.String())
 
@@ -387,7 +387,7 @@
 Rebuild with ART_BOOT_IMAGE_EXTRA_ARGS="--runtime-arg -verbose:verifier" to see verification errors.`
 
 func bootImageProfileRule(ctx android.SingletonContext, info *bootJarsInfo, missingDeps []string) android.WritablePath {
-	if len(info.global.BootImageProfiles) == 0 {
+	if !info.global.UseProfileForBootImage || ctx.Config().IsPdkBuild() || ctx.Config().UnbundledBuild() {
 		return nil
 	}
 
@@ -396,13 +396,25 @@
 	rule := android.NewRuleBuilder()
 	rule.MissingDeps(missingDeps)
 
-	var bootImageProfile string
+	var bootImageProfile android.Path
 	if len(info.global.BootImageProfiles) > 1 {
 		combinedBootImageProfile := info.dir.Join(ctx, "boot-image-profile.txt")
-		rule.Command().Text("cat").Inputs(info.global.BootImageProfiles).Text(">").Output(combinedBootImageProfile.String())
-		bootImageProfile = combinedBootImageProfile.String()
-	} else {
+		rule.Command().Text("cat").Inputs(info.global.BootImageProfiles).Text(">").Output(combinedBootImageProfile)
+		bootImageProfile = combinedBootImageProfile
+	} else if len(info.global.BootImageProfiles) == 1 {
 		bootImageProfile = info.global.BootImageProfiles[0]
+	} else {
+		// If not set, use the default.  Some branches like master-art-host don't have frameworks/base, so manually
+		// handle the case that the default is missing.  Those branches won't attempt to build the profile rule,
+		// and if they do they'll get a missing deps error.
+		defaultProfile := "frameworks/base/config/boot-image-profile.txt"
+		path := android.ExistentPathForSource(ctx, defaultProfile)
+		if path.Valid() {
+			bootImageProfile = path.Path()
+		} else {
+			missingDeps = append(missingDeps, defaultProfile)
+			bootImageProfile = android.PathForOutput(ctx, "missing")
+		}
 	}
 
 	profile := info.dir.Join(ctx, "boot.prof")
@@ -410,12 +422,12 @@
 	rule.Command().
 		Text(`ANDROID_LOG_TAGS="*:e"`).
 		Tool(tools.Profman).
-		FlagWithArg("--create-profile-from=", bootImageProfile).
-		FlagForEachInput("--apk=", info.preoptBootDex.Strings()).
+		FlagWithInput("--create-profile-from=", bootImageProfile).
+		FlagForEachInput("--apk=", info.preoptBootDex.Paths()).
 		FlagForEachArg("--dex-location=", info.preoptBootLocations).
-		FlagWithOutput("--reference-profile-file=", profile.String())
+		FlagWithOutput("--reference-profile-file=", profile)
 
-	rule.Install(profile.String(), "/system/etc/boot-image.prof")
+	rule.Install(profile, "/system/etc/boot-image.prof")
 
 	rule.Build(pctx, ctx, "bootJarsProfile", "profile boot jars")
 
@@ -439,16 +451,6 @@
 	for arch, _ := range info.images {
 		ctx.Strict("DEXPREOPT_IMAGE_"+arch.String(), info.images[arch].String())
 
-		var builtInstalled []string
-		for _, install := range info.installs[arch] {
-			builtInstalled = append(builtInstalled, install.From+":"+install.To)
-		}
-
-		var unstrippedBuiltInstalled []string
-		for _, install := range info.unstrippedInstalls[arch] {
-			unstrippedBuiltInstalled = append(unstrippedBuiltInstalled, install.From+":"+install.To)
-		}
-
 		ctx.Strict("DEXPREOPT_IMAGE_BUILT_INSTALLED_"+arch.String(), info.installs[arch].String())
 		ctx.Strict("DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_"+arch.String(), info.unstrippedInstalls[arch].String())
 		ctx.Strict("DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_"+arch.String(), info.vdexInstalls[arch].String())
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index 01e2c5e..104cd76 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -15,8 +15,6 @@
 package java
 
 import (
-	"path/filepath"
-
 	"github.com/google/blueprint"
 
 	"android/soong/android"
@@ -175,14 +173,3 @@
 		TransformZipAlign(ctx, output, tmpOutput)
 	}
 }
-
-type hiddenAPIPath struct {
-	path string
-}
-
-var _ android.Path = (*hiddenAPIPath)(nil)
-
-func (p *hiddenAPIPath) String() string { return p.path }
-func (p *hiddenAPIPath) Ext() string    { return filepath.Ext(p.path) }
-func (p *hiddenAPIPath) Base() string   { return filepath.Base(p.path) }
-func (p *hiddenAPIPath) Rel() string    { return p.path }
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index adbd356..ba8b3e1 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -170,14 +170,14 @@
 	rule.MissingDeps(missingDeps)
 
 	rule.Command().
-		Tool(pctx.HostBinToolPath(ctx, "hiddenapi").String()).
+		Tool(pctx.HostBinToolPath(ctx, "hiddenapi")).
 		Text("list").
-		FlagForEachInput("--boot-dex=", bootDexJars.Strings()).
-		FlagWithInputList("--public-stub-classpath=", publicStubPaths.Strings(), ":").
-		FlagWithInputList("--public-stub-classpath=", systemStubPaths.Strings(), ":").
-		FlagWithInputList("--public-stub-classpath=", testStubPaths.Strings(), ":").
-		FlagWithInputList("--core-platform-stub-classpath=", corePlatformStubPaths.Strings(), ":").
-		FlagWithOutput("--out-api-flags=", tempPath.String())
+		FlagForEachInput("--boot-dex=", bootDexJars).
+		FlagWithInputList("--public-stub-classpath=", publicStubPaths, ":").
+		FlagWithInputList("--public-stub-classpath=", systemStubPaths, ":").
+		FlagWithInputList("--public-stub-classpath=", testStubPaths, ":").
+		FlagWithInputList("--core-platform-stub-classpath=", corePlatformStubPaths, ":").
+		FlagWithOutput("--out-api-flags=", tempPath)
 
 	commitChangeForRestat(rule, tempPath, outputPath)
 
@@ -214,20 +214,20 @@
 	stubFlags := hiddenAPISingletonPaths(ctx).stubFlags
 
 	rule.Command().
-		Tool(android.PathForSource(ctx, "frameworks/base/tools/hiddenapi/generate_hiddenapi_lists.py").String()).
-		FlagWithInput("--csv ", stubFlags.String()).
-		Inputs(flagsCSV.Strings()).
+		Tool(android.PathForSource(ctx, "frameworks/base/tools/hiddenapi/generate_hiddenapi_lists.py")).
+		FlagWithInput("--csv ", stubFlags).
+		Inputs(flagsCSV).
 		FlagWithInput("--greylist ",
-			android.PathForSource(ctx, "frameworks/base/config/hiddenapi-greylist.txt").String()).
+			android.PathForSource(ctx, "frameworks/base/config/hiddenapi-greylist.txt")).
 		FlagWithInput("--greylist-ignore-conflicts ",
-			greylistIgnoreConflicts.String()).
+			greylistIgnoreConflicts).
 		FlagWithInput("--greylist-max-p ",
-			android.PathForSource(ctx, "frameworks/base/config/hiddenapi-greylist-max-p.txt").String()).
+			android.PathForSource(ctx, "frameworks/base/config/hiddenapi-greylist-max-p.txt")).
 		FlagWithInput("--greylist-max-o-ignore-conflicts ",
-			android.PathForSource(ctx, "frameworks/base/config/hiddenapi-greylist-max-o.txt").String()).
+			android.PathForSource(ctx, "frameworks/base/config/hiddenapi-greylist-max-o.txt")).
 		FlagWithInput("--blacklist ",
-			android.PathForSource(ctx, "frameworks/base/config/hiddenapi-force-blacklist.txt").String()).
-		FlagWithOutput("--output ", tempPath.String())
+			android.PathForSource(ctx, "frameworks/base/config/hiddenapi-force-blacklist.txt")).
+		FlagWithOutput("--output ", tempPath)
 
 	commitChangeForRestat(rule, tempPath, outputPath)
 
@@ -243,8 +243,8 @@
 
 	outputPath := hiddenAPISingletonPaths(ctx).flags
 
-	rule.Command().Text("rm").Flag("-f").Output(outputPath.String())
-	rule.Command().Text("touch").Output(outputPath.String())
+	rule.Command().Text("rm").Flag("-f").Output(outputPath)
+	rule.Command().Text("touch").Output(outputPath)
 
 	rule.Build(pctx, ctx, "emptyHiddenAPIFlagsFile", "empty hiddenapi flags")
 
@@ -269,10 +269,10 @@
 	outputPath := hiddenAPISingletonPaths(ctx).metadata
 
 	rule.Command().
-		Tool(android.PathForSource(ctx, "frameworks/base/tools/hiddenapi/merge_csv.py").String()).
-		Inputs(metadataCSV.Strings()).
+		Tool(android.PathForSource(ctx, "frameworks/base/tools/hiddenapi/merge_csv.py")).
+		Inputs(metadataCSV).
 		Text(">").
-		Output(outputPath.String())
+		Output(outputPath)
 
 	rule.Build(pctx, ctx, "hiddenAPIGreylistMetadataFile", "hiddenapi greylist metadata")
 
@@ -284,15 +284,15 @@
 // the rule.
 func commitChangeForRestat(rule *android.RuleBuilder, tempPath, outputPath android.WritablePath) {
 	rule.Restat()
-	rule.Temporary(tempPath.String())
+	rule.Temporary(tempPath)
 	rule.Command().
 		Text("(").
 		Text("if").
-		Text("cmp -s").Input(tempPath.String()).Output(outputPath.String()).Text(";").
+		Text("cmp -s").Input(tempPath).Output(outputPath).Text(";").
 		Text("then").
-		Text("rm").Input(tempPath.String()).Text(";").
+		Text("rm").Input(tempPath).Text(";").
 		Text("else").
-		Text("mv").Input(tempPath.String()).Output(outputPath.String()).Text(";").
+		Text("mv").Input(tempPath).Output(outputPath).Text(";").
 		Text("fi").
 		Text(")")
 }
diff --git a/java/testing.go b/java/testing.go
index 6febfa1..bec3c0b 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -18,6 +18,7 @@
 	"fmt"
 
 	"android/soong/android"
+	"android/soong/dexpreopt"
 )
 
 func TestConfig(buildDir string, env map[string]string) android.Config {
@@ -30,6 +31,9 @@
 	config := android.TestArchConfig(buildDir, env)
 	config.TestProductVariables.DeviceSystemSdkVersions = []string{"14", "15"}
 
+	pathCtx := android.PathContextForTesting(config, nil)
+	setDexpreoptGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx))
+
 	return config
 }