Enable cc_binary in mixed build.

Bug: 216114082
Test: Run mixed build on adbd apex and verify the pavkaged adbd binary;
add unit test.
Change-Id: Id11549a7952a7ce5ac02988b88b747bbfe8339ff

Change-Id: If01efe076c223886278f466b65628602bff3a964
diff --git a/cc/binary.go b/cc/binary.go
index 54fd339..6c7d581 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -70,6 +70,7 @@
 // cc_binary produces a binary that is runnable on a device.
 func BinaryFactory() android.Module {
 	module, _ := newBinary(android.HostAndDeviceSupported, true)
+	module.bazelHandler = &ccBinaryBazelHandler{module: module}
 	return module.Init()
 }
 
@@ -556,6 +557,28 @@
 	})
 }
 
+type ccBinaryBazelHandler struct {
+	android.BazelHandler
+
+	module *Module
+}
+
+func (handler *ccBinaryBazelHandler) GenerateBazelBuildActions(ctx android.ModuleContext, label string) bool {
+	bazelCtx := ctx.Config().BazelContext
+	filePaths, ok := bazelCtx.GetOutputFiles(label, android.GetConfigKey(ctx))
+	if ok {
+		if len(filePaths) != 1 {
+			ctx.ModuleErrorf("expected exactly one output file for '%s', but got %s", label, filePaths)
+			return false
+		}
+		outputFilePath := android.PathForBazelOut(ctx, filePaths[0])
+		handler.module.outputFile = android.OptionalPathForPath(outputFilePath)
+		// TODO(b/220164721): We need to decide if we should return the stripped as the unstripped.
+		handler.module.linker.(*binaryDecorator).unstrippedOutputFile = outputFilePath
+	}
+	return ok
+}
+
 func binaryBp2build(ctx android.TopDownMutatorContext, m *Module, typ string) {
 	baseAttrs := bp2BuildParseBaseProps(ctx, m)
 	binaryLinkerAttrs := bp2buildBinaryLinkerProps(ctx, m)
diff --git a/cc/binary_test.go b/cc/binary_test.go
new file mode 100644
index 0000000..8ec3871
--- /dev/null
+++ b/cc/binary_test.go
@@ -0,0 +1,51 @@
+// Copyright 2022 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cc
+
+import (
+	"testing"
+
+	"android/soong/android"
+)
+
+func TestCcBinaryWithBazel(t *testing.T) {
+	bp := `
+cc_binary {
+	name: "foo",
+	srcs: ["foo.cc"],
+	bazel_module: { label: "//foo/bar:bar" },
+}`
+	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
+	config.BazelContext = android.MockBazelContext{
+		OutputBaseDir: "outputbase",
+		LabelToOutputFiles: map[string][]string{
+			"//foo/bar:bar": []string{"foo"},
+		},
+	}
+	ctx := testCcWithConfig(t, config)
+
+	binMod := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Module()
+	producer := binMod.(android.OutputFileProducer)
+	outputFiles, err := producer.OutputFiles("")
+	if err != nil {
+		t.Errorf("Unexpected error getting cc_binary outputfiles %s", err)
+	}
+	expectedOutputFiles := []string{"outputbase/execroot/__main__/foo"}
+	android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings())
+
+	unStrippedFilePath := binMod.(*Module).UnstrippedOutputFile()
+	expectedUnStrippedFile := "outputbase/execroot/__main__/foo"
+	android.AssertStringEquals(t, "Unstripped output file", expectedUnStrippedFile, unStrippedFilePath.String())
+}