Add OutputFilesProvider support for singleton

This CL also changes to use OutputFilesProvider on rust module, which
has singleton involved.

Test: CI
Bug: 339477385
Bug: 348494466
Change-Id: Idc5c0fb9f8425f09184d5b73531ee3052e5a076c
diff --git a/android/module.go b/android/module.go
index a75f03f..7e34a3f 100644
--- a/android/module.go
+++ b/android/module.go
@@ -2527,34 +2527,44 @@
 // reading OutputFilesProvider before GenerateBuildActions is finished.
 // If a module doesn't have the OutputFilesProvider, nil is returned.
 func outputFilesForModuleFromProvider(ctx PathContext, module blueprint.Module, tag string) (Paths, error) {
-	// TODO: support OutputFilesProvider for singletons
-	mctx, ok := ctx.(ModuleContext)
-	if !ok {
-		return nil, nil
-	}
-	if mctx.Module() != module {
-		if outputFilesProvider, ok := OtherModuleProvider(mctx, module, OutputFilesProvider); ok {
+	var outputFilesProvider OutputFilesInfo
+
+	if mctx, isMctx := ctx.(ModuleContext); isMctx {
+		if mctx.Module() != module {
+			outputFilesProvider, _ = OtherModuleProvider(mctx, module, OutputFilesProvider)
+		} else {
 			if tag == "" {
-				return outputFilesProvider.DefaultOutputFiles, nil
-			} else if taggedOutputFiles, hasTag := outputFilesProvider.TaggedOutputFiles[tag]; hasTag {
+				return mctx.Module().base().outputFiles.DefaultOutputFiles, nil
+			} else if taggedOutputFiles, hasTag := mctx.Module().base().outputFiles.TaggedOutputFiles[tag]; hasTag {
 				return taggedOutputFiles, nil
 			} else {
-				return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+				return nil, fmt.Errorf("unsupported tag %q for module getting its own output files", tag)
 			}
 		}
-	} else {
+	} else if cta, isCta := ctx.(*singletonContextAdaptor); isCta {
+		providerData, _ := cta.moduleProvider(module, OutputFilesProvider)
+		outputFilesProvider, _ = providerData.(OutputFilesInfo)
+	}
+	// TODO: Add a check for skipped context
+
+	if !outputFilesProvider.isEmpty() {
 		if tag == "" {
-			return mctx.Module().base().outputFiles.DefaultOutputFiles, nil
-		} else if taggedOutputFiles, hasTag := mctx.Module().base().outputFiles.TaggedOutputFiles[tag]; hasTag {
+			return outputFilesProvider.DefaultOutputFiles, nil
+		} else if taggedOutputFiles, hasTag := outputFilesProvider.TaggedOutputFiles[tag]; hasTag {
 			return taggedOutputFiles, nil
 		} else {
-			return nil, fmt.Errorf("unsupported tag %q for module getting its own output files", tag)
+			return nil, fmt.Errorf("unsupported module reference tag %q", tag)
 		}
 	}
+
 	// TODO: Add a check for param module not having OutputFilesProvider set
 	return nil, nil
 }
 
+func (o OutputFilesInfo) isEmpty() bool {
+	return o.DefaultOutputFiles == nil && o.TaggedOutputFiles == nil
+}
+
 type OutputFilesInfo struct {
 	// default output files when tag is an empty string ""
 	DefaultOutputFiles Paths