Add initial Skylark API for Android rules.

--
MOS_MIGRATED_REVID=115364137
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index 8a1eb0d..72bccc0 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -727,6 +727,7 @@
         ":packages-internal",
         ":util",
         ":vfs",
+        "//src/main/java/com/google/devtools/build/lib:skylarkinterface",
         "//src/main/java/com/google/devtools/build/lib/actions",
         "//src/main/java/com/google/devtools/build/lib/rules/cpp",
         "//src/main/java/com/google/devtools/common/options",
diff --git a/src/main/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspect.java b/src/main/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspect.java
index 73aa5ac..aa24d5b 100644
--- a/src/main/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspect.java
@@ -59,7 +59,6 @@
 import com.google.devtools.build.lib.packages.BuildType;
 import com.google.devtools.build.lib.packages.Package;
 import com.google.devtools.build.lib.packages.Rule;
-import com.google.devtools.build.lib.rules.android.AndroidCommon;
 import com.google.devtools.build.lib.rules.android.AndroidIdeInfoProvider;
 import com.google.devtools.build.lib.rules.android.AndroidIdeInfoProvider.SourceDirectory;
 import com.google.devtools.build.lib.rules.android.AndroidSdkProvider;
@@ -429,7 +428,7 @@
       builder.addResources(artifactLocation);
     }
 
-    builder.setJavaPackage(AndroidCommon.getJavaPackage(ruleContext));
+    builder.setJavaPackage(provider.getJavaPackage());
 
     boolean hasIdlSources = !provider.getIdlSrcs().isEmpty();
     builder.setHasIdlSources(hasIdlSources);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java
index e52f2fa..7e022c8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java
@@ -246,6 +246,7 @@
       Iterable<Artifact> apksUnderTest) {
     AndroidIdeInfoProvider.Builder ideInfoProviderBuilder =
         new AndroidIdeInfoProvider.Builder()
+            .setJavaPackage(getJavaPackage(ruleContext))
             .setIdlClassJar(idlHelper.getIdlClassJar())
             .setIdlSourceJar(idlHelper.getIdlSourceJar())
             .addIdlParcelables(idlHelper.getIdlParcelables())
@@ -602,12 +603,16 @@
             JavaRuntimeJarProvider.class,
             new JavaRuntimeJarProvider(javaCommon.getJavaCompilationArtifacts().getRuntimeJars()))
         .add(RunfilesProvider.class, RunfilesProvider.simple(getRunfiles()))
-        .add(
-            AndroidResourcesProvider.class, resourceApk.toResourceProvider(ruleContext.getLabel()))
+        .add(AndroidResourcesProvider.class, resourceApk.toResourceProvider(ruleContext.getLabel()))
         .add(
             AndroidIdeInfoProvider.class,
-            createAndroidIdeInfoProvider(ruleContext, androidSemantics, idlHelper,
-                resourceApk, zipAlignedApk, apksUnderTest))
+            createAndroidIdeInfoProvider(
+                ruleContext,
+                androidSemantics,
+                idlHelper,
+                resourceApk,
+                zipAlignedApk,
+                apksUnderTest))
         .add(
             JavaCompilationArgsProvider.class,
             new JavaCompilationArgsProvider(
@@ -620,6 +625,7 @@
             asNeverLink
                 ? jackCompilationHelper.compileAsNeverlinkLibrary()
                 : jackCompilationHelper.compileAsLibrary())
+        .addSkylarkTransitiveInfo(AndroidSkylarkApiProvider.NAME, new AndroidSkylarkApiProvider())
         .addOutputGroup(
             OutputGroupProvider.HIDDEN_TOP_LEVEL, collectHiddenTopLevelArtifacts(ruleContext))
         .addOutputGroup(JavaSemantics.SOURCE_JARS_OUTPUT_GROUP, transitiveSourceJars);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidIdeInfoProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidIdeInfoProvider.java
index 0cd44ad..43fa45c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidIdeInfoProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidIdeInfoProvider.java
@@ -127,6 +127,7 @@
     private Artifact apk = null;
     private Artifact idlClassJar = null;
     private Artifact idlSourceJar = null;
+    private String javaPackage = null;
     private final Set<SourceDirectory> resourceDirs = new LinkedHashSet<>();
     private final Set<SourceDirectory> assetDirs = new LinkedHashSet<>();
     private final Set<SourceDirectory> idlDirs = new LinkedHashSet<>();
@@ -136,6 +137,7 @@
 
     public AndroidIdeInfoProvider build() {
       return new AndroidIdeInfoProvider(
+          javaPackage,
           manifest,
           generatedManifest,
           apk,
@@ -149,6 +151,11 @@
           ImmutableList.copyOf(apksUnderTest));
     }
 
+    public Builder setJavaPackage(String javaPackage) {
+      this.javaPackage = javaPackage;
+      return this;
+    }
+
     public Builder setApk(Artifact apk) {
       Preconditions.checkState(this.apk == null);
       this.apk = apk;
@@ -315,6 +322,7 @@
     }
   }
 
+  private final String javaPackage;
   private final Artifact manifest;
   private final Artifact generatedManifest;
   private final Artifact signedApk;
@@ -327,7 +335,9 @@
   private final ImmutableCollection<Artifact> idlGeneratedJavaFiles;
   private final ImmutableCollection<Artifact> apksUnderTest;
 
-  AndroidIdeInfoProvider(@Nullable Artifact manifest,
+  AndroidIdeInfoProvider(
+      String javaPackage,
+      @Nullable Artifact manifest,
       @Nullable Artifact generatedManifest,
       @Nullable Artifact signedApk,
       @Nullable Artifact idlClassJar,
@@ -338,6 +348,7 @@
       ImmutableCollection<Artifact> idlSrcs,
       ImmutableCollection<Artifact> idlGeneratedJavaFiles,
       ImmutableCollection<Artifact> apksUnderTest) {
+    this.javaPackage = javaPackage;
     this.manifest = manifest;
     this.generatedManifest = generatedManifest;
     this.signedApk = signedApk;
@@ -351,6 +362,11 @@
     this.apksUnderTest = apksUnderTest;
   }
 
+  /** Returns java package for this target. */
+  public String getJavaPackage() {
+    return javaPackage;
+  }
+
   /** Returns the direct AndroidManifest. */
   @Nullable
   public Artifact getManifest() {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkApiProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkApiProvider.java
new file mode 100644
index 0000000..2c4a017
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkApiProvider.java
@@ -0,0 +1,62 @@
+// Copyright 2016 The Bazel Authors. 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 com.google.devtools.build.lib.rules.android;
+
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.rules.SkylarkApiProvider;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
+
+/**
+ * A class that exposes the Android providers to Skylark. It is intended to provide a
+ * simple and stable interface for Skylark users.
+ */
+@SkylarkModule(
+  name = "AndroidSkylarkApiProvider",
+  doc = "Provides access to information about Android rules"
+)
+public class AndroidSkylarkApiProvider extends SkylarkApiProvider {
+  /** The name of the field in Skylark used to access this class. */
+  public static final String NAME = "android";
+
+  @SkylarkCallable(
+    name = "apk",
+    structField = true,
+    allowReturnNones = true,
+    doc = "Returns an APK produced by this target."
+  )
+  public Artifact getApk() {
+    return getInfo().getProvider(AndroidIdeInfoProvider.class).getSignedApk();
+  }
+
+  @SkylarkCallable(
+    name = "java_package",
+    structField = true,
+    allowReturnNones = true,
+    doc = "Returns a java package for this target."
+  )
+  public String getJavaPackage() {
+    return getInfo().getProvider(AndroidIdeInfoProvider.class).getJavaPackage();
+  }
+
+  @SkylarkCallable(
+    name = "manifest",
+    structField = true,
+    allowReturnNones = true,
+    doc = "Returns a manifest file for this target."
+  )
+  public Artifact getManifest() {
+    return getInfo().getProvider(AndroidIdeInfoProvider.class).getManifest();
+  }
+}
diff --git a/src/main/protobuf/android_studio_ide_info.proto b/src/main/protobuf/android_studio_ide_info.proto
index 3b80f6e..9437a35 100644
--- a/src/main/protobuf/android_studio_ide_info.proto
+++ b/src/main/protobuf/android_studio_ide_info.proto
@@ -50,7 +50,7 @@
   repeated ArtifactLocation resources = 1;
   ArtifactLocation apk = 3;
   repeated ArtifactLocation dependency_apk = 4;
-  ArtifactLocation manifest= 5;
+  ArtifactLocation manifest = 5;
   string java_package = 7;
   bool has_idl_sources = 8;
   LibraryArtifact idl_jar = 9;
diff --git a/src/test/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspectTest.java b/src/test/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspectTest.java
index 11f8e06..2220848 100644
--- a/src/test/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspectTest.java
+++ b/src/test/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspectTest.java
@@ -590,10 +590,10 @@
               transform(
                   ruleInfo.getAndroidRuleIdeInfo().getResourcesList(), ARTIFACT_TO_RELATIVE_PATH))
           .containsExactly("com/google/example/res");
-      assertThat(ruleInfo.getAndroidRuleIdeInfo().getManifest().getRelativePath())
-          .isEqualTo("com/google/example/AndroidManifest.xml");
-      assertThat(ruleInfo.getAndroidRuleIdeInfo().getJavaPackage()).isEqualTo("com.google.example");
     }
+    assertThat(ruleInfo.getAndroidRuleIdeInfo().getManifest().getRelativePath())
+        .isEqualTo("com/google/example/AndroidManifest.xml");
+    assertThat(ruleInfo.getAndroidRuleIdeInfo().getJavaPackage()).isEqualTo("com.google.example");
 
     assertThat(ruleInfo.getDependenciesList()).containsExactly("//com/google/example:l1");
     assertThat(getIdeResolveFiles()).containsExactly(
@@ -647,12 +647,13 @@
               transform(
                   ruleInfo.getAndroidRuleIdeInfo().getResourcesList(), ARTIFACT_TO_RELATIVE_PATH))
           .containsExactly("com/google/example/res");
-      assertThat(ruleInfo.getAndroidRuleIdeInfo().getManifest().getRelativePath())
-          .isEqualTo("com/google/example/AndroidManifest.xml");
-      assertThat(ruleInfo.getAndroidRuleIdeInfo().getJavaPackage()).isEqualTo("com.google.example");
-      assertThat(ruleInfo.getAndroidRuleIdeInfo().getApk().getRelativePath())
-          .isEqualTo("com/google/example/b.apk");
     }
+    assertThat(ruleInfo.getAndroidRuleIdeInfo().getManifest().getRelativePath())
+        .isEqualTo("com/google/example/AndroidManifest.xml");
+    assertThat(ruleInfo.getAndroidRuleIdeInfo().getJavaPackage()).isEqualTo("com.google.example");
+    assertThat(ruleInfo.getAndroidRuleIdeInfo().getApk().getRelativePath())
+        .isEqualTo("com/google/example/b.apk");
+
 
     assertThat(ruleInfo.getDependenciesList()).containsExactly("//com/google/example:l1");
 
@@ -675,10 +676,6 @@
 
   @Test
   public void testAndroidInferredPackage() throws Exception {
-    if (!isNativeTest()) {
-      return;
-    }
-
     scratch.file(
         "java/com/google/example/BUILD",
         "android_library(",
@@ -753,10 +750,6 @@
 
   @Test
   public void testAndroidLibraryGeneratedManifestIsAddedToOutputGroup() throws Exception {
-    if (!isNativeTest()) {
-      return;
-    }
-
     scratch.file(
         "com/google/example/BUILD",
         "android_library(",
@@ -836,10 +829,6 @@
 
   @Test
   public void testNonConformingPackageName() throws Exception {
-    if (!isNativeTest()) {
-      return;
-    }
-
     scratch.file(
         "bad/package/google/example/BUILD",
         "android_library(",
diff --git a/src/test/java/com/google/devtools/build/lib/ideinfo/intellij_info.bzl b/src/test/java/com/google/devtools/build/lib/ideinfo/intellij_info.bzl
index 314ca1d..98c2a1b 100644
--- a/src/test/java/com/google/devtools/build/lib/ideinfo/intellij_info.bzl
+++ b/src/test/java/com/google/devtools/build/lib/ideinfo/intellij_info.bzl
@@ -112,6 +112,15 @@
           ),
           ide_resolve_files)
 
+def android_rule_ide_info(target, ctx):
+  if not hasattr(target, 'android'):
+    return None
+  return struct_omit_none(
+            java_package = target.android.java_package,
+            manifest = artifact_location(target.android.manifest),
+            apk = artifact_location(target.android.apk),
+        )
+
 
 def _aspect_impl(target, ctx):
   kind = get_kind(target, ctx)
@@ -133,12 +142,16 @@
     if is_java_rule(target, ctx):
       java_rule_ide_info, java_ide_resolve_files = java_rule_ide_info(target, ctx)
       ide_resolve_files = ide_resolve_files | java_ide_resolve_files
-      info = struct(
+
+      android_rule_ide_info = android_rule_ide_info(target, ctx)
+
+      info = struct_omit_none(
           label = str(target.label),
           kind = kind,
           dependencies = all_deps,
           build_file_artifact_location = build_file_artifact_location(ctx.build_file_path),
           java_rule_ide_info = java_rule_ide_info,
+          android_rule_ide_info = android_rule_ide_info,
           tags = ctx.rule.attr.tags,
       )
     else: