Allows android_binary and android_library to depend on targets that return CcInfo providers.

RELNOTES: android_binary and android_libary can now depend on targets providing
CcInfos.
PiperOrigin-RevId: 277804440
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryBaseRule.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryBaseRule.java
index 80a4080..eca4708 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryBaseRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibraryBaseRule.java
@@ -82,6 +82,7 @@
                 .copy("deps")
                 .allowedRuleClasses(AndroidRuleClasses.ALLOWED_DEPENDENCIES)
                 .allowedFileTypes()
+                .mandatoryProviders(AndroidRuleClasses.CONTAINS_CC_INFO_PARAMS)
                 .mandatoryProviders(JavaRuleClasses.CONTAINS_JAVA_PROVIDER)
                 .aspect(androidNeverlinkAspect))
         /* <!-- #BLAZE_RULE(android_library).ATTRIBUTE(exports) -->
@@ -94,6 +95,7 @@
             attr("exports", LABEL_LIST)
                 .allowedRuleClasses(AndroidRuleClasses.ALLOWED_DEPENDENCIES)
                 .allowedFileTypes(/*May not have files in exports!*/ )
+                .mandatoryProviders(AndroidRuleClasses.CONTAINS_CC_INFO_PARAMS)
                 .mandatoryProviders(JavaRuleClasses.CONTAINS_JAVA_PROVIDER)
                 .aspect(androidNeverlinkAspect))
         /* <!-- #BLAZE_RULE(android_library).ATTRIBUTE(exports_manifest) -->
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
index 0466d55..00f2941 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
@@ -54,6 +54,7 @@
 import com.google.devtools.build.lib.rules.android.AndroidConfiguration.ConfigurationDistinguisher;
 import com.google.devtools.build.lib.rules.android.databinding.DataBinding;
 import com.google.devtools.build.lib.rules.config.ConfigFeatureFlagProvider;
+import com.google.devtools.build.lib.rules.cpp.CcInfo;
 import com.google.devtools.build.lib.rules.cpp.CppConfiguration;
 import com.google.devtools.build.lib.rules.cpp.CppOptions;
 import com.google.devtools.build.lib.rules.java.JavaConfiguration;
@@ -205,6 +206,9 @@
 
   public static final String NOCOMPRESS_EXTENSIONS_ATTR = "nocompress_extensions";
 
+  public static final ImmutableList<SkylarkProviderIdentifier> CONTAINS_CC_INFO_PARAMS =
+      ImmutableList.of(SkylarkProviderIdentifier.forKey(CcInfo.PROVIDER.getKey()));
+
   /** The default label of android_sdk option */
   public static LabelLateBoundDefault<?> getAndroidSdkLabel(Label androidSdk) {
     return LabelLateBoundDefault.fromTargetConfiguration(
@@ -583,6 +587,7 @@
                   .cfg(TransitionFactories.of(ANDROID_SPLIT_TRANSITION))
                   .allowedRuleClasses(ALLOWED_DEPENDENCIES)
                   .allowedFileTypes()
+                  .mandatoryProviders(CONTAINS_CC_INFO_PARAMS)
                   .mandatoryProviders(JavaRuleClasses.CONTAINS_JAVA_PROVIDER)
                   .mandatoryProviders(
                       SkylarkProviderIdentifier.forKey(AndroidResourcesInfo.PROVIDER.getKey()),
diff --git a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryTest.java b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryTest.java
index 6850489..a88657b 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryTest.java
@@ -53,6 +53,7 @@
 import com.google.devtools.build.lib.rules.android.AndroidRuleClasses.MultidexMode;
 import com.google.devtools.build.lib.rules.android.deployinfo.AndroidDeployInfoOuterClass.AndroidDeployInfo;
 import com.google.devtools.build.lib.rules.cpp.CppFileTypes;
+import com.google.devtools.build.lib.rules.cpp.CppLinkAction;
 import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider;
 import com.google.devtools.build.lib.rules.java.JavaCompileAction;
 import com.google.devtools.build.lib.rules.java.JavaInfo;
@@ -250,6 +251,125 @@
   }
 
   @Test
+  public void testCcInfoDeps() throws Exception {
+    scratch.file(
+        "java/a/cc_info.bzl",
+        "def _impl(ctx):",
+        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
+        "  feature_configuration = cc_common.configure_features(",
+        "    ctx = ctx,",
+        "    cc_toolchain = cc_toolchain,",
+        "    requested_features = ctx.features,",
+        "    unsupported_features = ctx.disabled_features,",
+        "  )",
+        "  library_to_link = cc_common.create_library_to_link(",
+        "    actions=ctx.actions, feature_configuration=feature_configuration, ",
+        "    cc_toolchain = cc_toolchain, ",
+        "    static_library=ctx.file.static_library)",
+        "  linking_context = cc_common.create_linking_context(libraries_to_link=[library_to_link],",
+        "    user_link_flags=ctx.attr.user_link_flags)",
+        "  return [CcInfo(linking_context=linking_context)]",
+        "cc_info = rule(",
+        "  implementation=_impl,",
+        "  fragments = [\"cpp\"],",
+        "  attrs = {",
+        "    'srcs': attr.label_list(allow_files=True),",
+        "    'user_link_flags' : attr.string_list(),",
+        "    'static_library': attr.label(allow_single_file=True),",
+        "    '_cc_toolchain': attr.label(default=Label('//java/a:alias'))",
+        "  },",
+        ");");
+    scratch.file(
+        "java/a/BUILD",
+        "load('//java/a:cc_info.bzl', 'cc_info')",
+        "cc_toolchain_alias(name='alias')",
+        "android_binary(",
+        "    name = 'a',",
+        "    manifest = 'AndroidManifest.xml',",
+        "    multidex = 'native',",
+        "    deps = [':cc_info'],",
+        ")",
+        "cc_info(",
+        "    name = 'cc_info',",
+        "    user_link_flags = ['-first_flag', '-second_flag'],",
+        "    static_library = 'cc_info.a',",
+        ")");
+
+    ConfiguredTarget app = getConfiguredTarget("//java/a:a");
+
+    Artifact copiedLib = getOnlyElement(getNativeLibrariesInApk(app));
+    Artifact linkedLib = getOnlyElement(getGeneratingAction(copiedLib).getInputs());
+    CppLinkAction action = (CppLinkAction) getGeneratingAction(linkedLib);
+
+    assertThat(action.getArguments()).containsAtLeast("-first_flag", "-second_flag");
+
+    Iterable<Artifact> linkInputs = action.getInputs();
+    assertThat(ActionsTestUtil.baseArtifactNames(linkInputs)).contains("cc_info.a");
+  }
+
+  @Test
+  public void testCcInfoDepsViaAndroidLibrary() throws Exception {
+    scratch.file(
+        "java/a/cc_info.bzl",
+        "def _impl(ctx):",
+        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
+        "  feature_configuration = cc_common.configure_features(",
+        "    ctx = ctx,",
+        "    cc_toolchain = cc_toolchain,",
+        "    requested_features = ctx.features,",
+        "    unsupported_features = ctx.disabled_features,",
+        "  )",
+        "  library_to_link = cc_common.create_library_to_link(",
+        "    actions=ctx.actions, feature_configuration=feature_configuration, ",
+        "    cc_toolchain = cc_toolchain, ",
+        "    static_library=ctx.file.static_library)",
+        "  linking_context = cc_common.create_linking_context(libraries_to_link=[library_to_link],",
+        "    user_link_flags=ctx.attr.user_link_flags)",
+        "  return [CcInfo(linking_context=linking_context)]",
+        "cc_info = rule(",
+        "  implementation=_impl,",
+        "  fragments = [\"cpp\"],",
+        "  attrs = {",
+        "    'srcs': attr.label_list(allow_files=True),",
+        "    'user_link_flags' : attr.string_list(),",
+        "    'static_library': attr.label(allow_single_file=True),",
+        "    '_cc_toolchain': attr.label(default=Label('//java/a:alias'))",
+        "  },",
+        ");");
+    scratch.file(
+        "java/a/BUILD",
+        "load('//java/a:cc_info.bzl', 'cc_info')",
+        "cc_toolchain_alias(name='alias')",
+        "android_binary(",
+        "    name = 'a',",
+        "    manifest = 'AndroidManifest.xml',",
+        "    multidex = 'native',",
+        "    deps = [':liba'],",
+        ")",
+        "android_library(",
+        "    name = 'liba',",
+        "    srcs = ['a.java'],",
+        "    deps = [':cc_info'],",
+        ")",
+        "cc_info(",
+        "    name = 'cc_info',",
+        "    user_link_flags = ['-first_flag', '-second_flag'],",
+        "    static_library = 'cc_info.a',",
+        ")");
+
+    ConfiguredTarget app = getConfiguredTarget("//java/a:a");
+
+    Artifact copiedLib = getOnlyElement(getNativeLibrariesInApk(app));
+    Artifact linkedLib = getOnlyElement(getGeneratingAction(copiedLib).getInputs());
+    CppLinkAction action = (CppLinkAction) getGeneratingAction(linkedLib);
+
+    assertThat(action.getArguments()).containsAtLeast("-first_flag", "-second_flag");
+
+    Iterable<Artifact> linkInputs = action.getInputs();
+    assertThat(ActionsTestUtil.baseArtifactNames(linkInputs)).contains("cc_info.a");
+  }
+
+  @Test
   public void testJavaPluginProcessorPath() throws Exception {
     scratch.file(
         "java/test/BUILD",