Implementation of the gradle-android Docker file and build_android_library github action. (#7143)

This implements a new Github action `.github/workflows/build_android_library.yml` that runs our workflow to build IREE's TFLite Java bindings via  `build_tools/gradle/build_tflite_android_library.sh`.

The Github Action uses a new `gradle-android/Docker` file to produce consistent repeatable builds locally and remote. 

On some systems, gradle fails to run the `externalNativeBuild` task with an unexplained NullPointer error. To get around this. We manually build the native IREE TFLite compatibility shim with [Android cross-compilation](https://google.github.io/iree/building-from-source/android/). The resulting library is copied into the `jniLibs` folder to be included directly in the final library, while native build tasks are skipped by gradle. 

Additional changes to fix recent issues with the gradle build: 
* Switching to the support Android library for  the `NonNull` annotation
* Encapsulating `mlir-tablegen` target with the `IREE_BUILD_COMPILER ` in `build_tools/cmake/iree_copts.cmake`. This caused build failure when compiling the host-tooling without compiler targets (avoid building all of LLVM) since tablegen targets can't compile without other compiler dependencies hidden behind this flag. 
diff --git a/.github/workflows/android_tflite_oneshot_build.yml b/.github/workflows/android_tflite_oneshot_build.yml
new file mode 100644
index 0000000..1c48213
--- /dev/null
+++ b/.github/workflows/android_tflite_oneshot_build.yml
@@ -0,0 +1,27 @@
+# Builds the TFLite Java Bindings Android Library using the gradle-android
+# Docker image.
+name: Build TFLite Android Library
+
+on:
+  workflow_dispatch:
+
+jobs:
+  build_android_with_docker:
+    runs-on: ubuntu-latest
+    env:
+      ANDROID_CONTAINER: "gcr.io/iree-oss/gradle-android@sha256:54cddc42e13d63da5adf495acb4e96c2773b66a1169cf8a9aac26a21f4166e2e"
+    steps:
+      - uses: actions/checkout@v2
+        with:
+          submodules: true
+      - name: Execute Android Build
+        run: |
+          docker run --rm \
+          -w=/work \
+          -v $PWD:/work \
+          "${ANDROID_CONTAINER}" \
+          bash -c build_tools/gradle/build_tflite_android_library.sh
+      - uses: actions/upload-artifact@v2
+        with:
+          path: ./bindings/tflite/java/build/outputs/aar/*.aar
+          retention-days: 1
diff --git a/bindings/tflite/java/build.gradle b/bindings/tflite/java/build.gradle
index fe521a1..325f6f1 100644
--- a/bindings/tflite/java/build.gradle
+++ b/bindings/tflite/java/build.gradle
@@ -54,6 +54,7 @@
                 exclude('tests/**') // Don't build tests into the library
             }
             jni.srcDirs = ['org/tensorflow/lite/native']
+            jniLibs.srcDirs = ['jniLibs/']
         }
     }
 
diff --git a/bindings/tflite/java/org/tensorflow/lite/Interpreter.java b/bindings/tflite/java/org/tensorflow/lite/Interpreter.java
index 80c0b05..4500939 100644
--- a/bindings/tflite/java/org/tensorflow/lite/Interpreter.java
+++ b/bindings/tflite/java/org/tensorflow/lite/Interpreter.java
@@ -8,7 +8,7 @@
 
 package org.tensorflow.lite;
 
-import androidx.annotation.NonNull;
+import android.support.annotation.NonNull;
 import java.nio.Buffer;
 import java.nio.ByteBuffer;
 import java.util.HashMap;
diff --git a/build_tools/cmake/iree_copts.cmake b/build_tools/cmake/iree_copts.cmake
index 5a92b6f..e477eea 100644
--- a/build_tools/cmake/iree_copts.cmake
+++ b/build_tools/cmake/iree_copts.cmake
@@ -391,12 +391,12 @@
 #-------------------------------------------------------------------------------
 # Third party: llvm-project
 #-------------------------------------------------------------------------------
-
-set(MLIR_TABLEGEN_EXE mlir-tblgen)
-# iree-tblgen is not defined using the add_tablegen mechanism as other TableGen
-# tools in LLVM.
-iree_get_executable_path(IREE_TABLEGEN_EXE iree-tblgen)
-
+if(IREE_BUILD_COMPILER)
+  set(MLIR_TABLEGEN_EXE mlir-tblgen)
+  # iree-tblgen is not defined using the add_tablegen mechanism as other TableGen
+  # tools in LLVM.
+  iree_get_executable_path(IREE_TABLEGEN_EXE iree-tblgen)
+endif()
 #-------------------------------------------------------------------------------
 # Third party: mlir-emitc
 #-------------------------------------------------------------------------------
diff --git a/build_tools/docker/gradle-android/Dockerfile b/build_tools/docker/gradle-android/Dockerfile
new file mode 100644
index 0000000..fb7b98b
--- /dev/null
+++ b/build_tools/docker/gradle-android/Dockerfile
@@ -0,0 +1,63 @@
+# Copyright 2021 The IREE Authors
+#
+# Licensed under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+# An image for cross-compiling IREE's TFLite Java Bindings with Gradle and
+# CMake.
+
+ARG JDK_VERSION=11
+
+ARG GRADLE_VERSION=7.1.1
+ARG GRADLE_DIST=bin
+
+ARG ANDROID_SDK_VERSION=7583922
+ARG ANDROID_NDK_VERSION=21.4.7075529
+
+FROM gcr.io/iree-oss/util@sha256:40846b4aea5886af3250399d6adfdb3e1195a8b0177706bb0375e812d62dc49c AS install-deps
+ARG GRADLE_VERSION
+ARG GRADLE_DIST
+ARG ANDROID_SDK_VERSION
+
+# Download and install Gradle
+RUN cd /opt && \
+    wget -q https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-${GRADLE_DIST}.zip && \
+    unzip gradle*.zip && \
+    rm gradle*.zip && \
+    ln -s /opt/gradle-${GRADLE_VERSION}/bin/gradle /usr/bin/gradle
+
+# Download and install Android SDK
+# Note: Uses the latest SDK version from https://developer.android.com/studio,
+# however Gradle will automatically download any additional SDK/tooling versions
+# as necessary.
+ENV ANDROID_SDK_ROOT /opt/android-sdk
+RUN mkdir -p ${ANDROID_SDK_ROOT}/cmdline-tools && \
+    wget -q https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_VERSION}_latest.zip && \
+    unzip *tools*linux*.zip -d ${ANDROID_SDK_ROOT}/cmdline-tools && \
+    mv ${ANDROID_SDK_ROOT}/cmdline-tools/cmdline-tools ${ANDROID_SDK_ROOT}/cmdline-tools/tools && \
+    rm *tools*linux*.zip
+
+FROM gcr.io/iree-oss/cmake@sha256:9d9953acf5ca0cf1ff3e8de32f10f24dfab1c4e8ec5d1fc047f556024ee4bed6 as final
+ARG ANDROID_SDK_VERSION
+ARG ANDROID_NDK_VERSION
+ARG GRADLE_VERSION
+ENV ANDROID_SDK_ROOT /opt/android-sdk
+
+# Download and install openjdk-11
+ARG JDK_VERSION
+RUN apt-get update && apt-get install -y openjdk-11-jdk
+
+# Copy /opt/ (Gradle + Android SDK) thenlink Gradle bin
+COPY --from=install-deps /opt/ /opt/
+RUN  ln -s /opt/gradle-${GRADLE_VERSION}/bin/gradle /usr/bin/gradle
+
+# Accept the license agreements of the Android SDK components
+RUN yes | ${ANDROID_SDK_ROOT}/cmdline-tools/tools/bin/sdkmanager --licenses
+
+# Install the Android NDK
+RUN /opt/android-sdk/cmdline-tools/tools/bin/sdkmanager --install "ndk;$ANDROID_NDK_VERSION"
+
+# Define environment variables for the NDK/SDK
+ENV ANDROID_HOME ${ANDROID_SDK_ROOT}
+ENV ANDROID_NDK /opt/android-sdk/ndk/${ANDROID_NDK_VERSION}
diff --git a/build_tools/docker/manage_images.py b/build_tools/docker/manage_images.py
index cce0114..03dfbbe 100755
--- a/build_tools/docker/manage_images.py
+++ b/build_tools/docker/manage_images.py
@@ -60,6 +60,7 @@
         'cmake-bazel-frontends-vulkan', 'swiftshader'
     ],
     'cmake-bazel-frontends-nvidia': ['cmake-bazel-frontends-vulkan'],
+    'gradle-android': ['cmake'],
     'rbe-toolchain': ['vulkan'],
     'samples': ['cmake-python-swiftshader'],
     'swiftshader': ['cmake'],
diff --git a/build_tools/docker/prod_digests.txt b/build_tools/docker/prod_digests.txt
index a5ec718..c7e88ec 100644
--- a/build_tools/docker/prod_digests.txt
+++ b/build_tools/docker/prod_digests.txt
@@ -19,3 +19,4 @@
 gcr.io/iree-oss/samples@sha256:d9ca1dbdcf4fa2b9dd8f032b42b9a74b9b5c5210d823528ea5874dfeec13444a
 gcr.io/iree-oss/cmake-emscripten@sha256:6dd6228cd482f7bbc64bca1ee7618a55eda408148e6d6588c58e98f89780a279
 gcr.io/iree-oss/cmake-gcc@sha256:49bd84535b82012e83de15a8f1ca847076b359a7bd5a8dabda7e76abb43f32e3
+gcr.io/iree-oss/gradle-android@sha256:54cddc42e13d63da5adf495acb4e96c2773b66a1169cf8a9aac26a21f4166e2e
diff --git a/build_tools/gradle/build_tflite_android_library.sh b/build_tools/gradle/build_tflite_android_library.sh
new file mode 100755
index 0000000..e49c6da
--- /dev/null
+++ b/build_tools/gradle/build_tflite_android_library.sh
@@ -0,0 +1,94 @@
+#!/bin/bash
+# Copyright 2021 The IREE Authors
+#
+# Licensed under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+# Cross-compile IREE's TFLite Java Bindings with Gradle and CMake. Produces an
+# iree-tflite-bindings-debug.aar and an iree-tflite-bindings-release.aar
+# library under bindings/tflite/java/output. Designed for CI, but can be run
+# manually.
+
+set -x
+set -e
+set -o pipefail
+
+# --------------------------------------------------------------------------- #
+ROOT_DIR=$(git rev-parse --show-toplevel)
+
+CMAKE_BIN=${CMAKE_BIN:-$(which cmake)}
+
+"${CMAKE_BIN?}" --version
+ninja --version
+gradle --version
+
+cd ${ROOT_DIR?}
+
+# --------------------------------------------------------------------------- #
+# Build the host libraries
+
+HOST_BUILD_DIR=${ROOT_DIR?}/build-host
+HOST_INSTALL_DIR=${HOST_BUILD_DIR}/install
+
+cmake -G Ninja -B ${HOST_BUILD_DIR} \
+  -DIREE_BUILD_COMPILER=OFF \
+  -DIREE_BUILD_TESTS=OFF \
+  -DIREE_BUILD_SAMPLES=OFF \
+  -DCMAKE_C_COMPILER=clang \
+  -DCMAKE_CXX_COMPILER=clang++ \
+  -DCMAKE_INSTALL_PREFIX=${HOST_INSTALL_DIR} .
+
+cmake --build ${HOST_BUILD_DIR} --target install
+
+# --------------------------------------------------------------------------- #
+# Build native libraries
+
+ANDROID_BUILD_DIR=${ROOT_DIR?}/build-android
+
+# Todo: Support multiple ABIs. For now we build a singe abi: arm64.
+ANDROID_ABI=arm64-v8a
+
+cmake -G Ninja -B ${ANDROID_BUILD_DIR} \
+  -DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK}/build/cmake/android.toolchain.cmake" \
+  -DIREE_HOST_BINARY_ROOT="${HOST_INSTALL_DIR}" \
+  -DANDROID_ABI="${ANDROID_ABI}" \
+  -DANDROID_PLATFORM="android-29" \
+  -DIREE_BUILD_COMPILER=OFF \
+  -DIREE_BUILD_BINDINGS_TFLITE=ON \
+  -DIREE_BUILD_BINDINGS_TFLITE_JAVA=ON \
+  -DIREE_BUILD_TESTS=OFF \
+  -DIREE_BUILD_SAMPLES=OFF \
+  -DIREE_BUILD_PYTHON_BINDINGS=OFF  .
+
+cmake --build  ${ANDROID_BUILD_DIR}  --target iree-tflite-bindings
+
+NATIVE_LIBRARY=${ANDROID_BUILD_DIR}/bindings/tflite/java/org/tensorflow/lite/native/libiree-tflite-bindings.so
+
+# --------------------------------------------------------------------------- #
+# Setup the gradle build with native libraries
+
+BINDINGS_DIR=${ROOT_DIR?}/bindings/tflite/java
+cd ${BINDINGS_DIR}
+
+# Copy the native library(s) to the jniLibs folder
+mkdir -p jniLibs/${ANDROID_ABI}
+cp ${NATIVE_LIBRARY} jniLibs/${ANDROID_ABI}
+
+# --------------------------------------------------------------------------- #
+# Build the Android library
+
+gradle wrapper
+
+# Note: since we're providing the native libraries, we omit the tasks that
+# generate them from the build.gradle.
+./gradlew build \
+  -x externalNativeBuildDebug \
+  -x externalNativeBuildCleanDebug \
+  -x externalNativeBuildRelease \
+  -x externalNativeBuildCleanRelease \
+  -x cmakeConfigureHost \
+  -x cmakeBuildHost
+
+echo "Android Library Artifacts:"
+ls build/outputs/aar/