Merge "Require lint when building release target"
diff --git a/buildSrc/src/main/groovy/android/support/SupportLibraryPlugin.groovy b/buildSrc/src/main/groovy/android/support/SupportLibraryPlugin.groovy
index 333a9f4..f1f6a04 100644
--- a/buildSrc/src/main/groovy/android/support/SupportLibraryPlugin.groovy
+++ b/buildSrc/src/main/groovy/android/support/SupportLibraryPlugin.groovy
@@ -46,29 +46,57 @@
         LibraryExtension library =
                 project.getExtensions().findByType(LibraryExtension.class);
 
-        library.setCompileSdkVersion(project.ext.currentSdk)
+        library.compileSdkVersion project.ext.currentSdk
 
-        // Main sourceSet related options
+        // We use a non-standard manifest path.
         AndroidSourceSet mainSet = library.getSourceSets().findByName("main");
-        mainSet.getManifest().srcFile("AndroidManifest.xml");
+        mainSet.manifest.srcFile 'AndroidManifest.xml'
 
-        // Update the version meta-data in each Manifest
-        library.getDefaultConfig().addManifestPlaceholders(
-                ["support-version": project.rootProject.ext.supportVersion])
+        library.defaultConfig {
+            // Update the version meta-data in each Manifest.
+            addManifestPlaceholders(["support-version": project.rootProject.ext.supportVersion])
 
-        // Set test related options
-        library.getDefaultConfig().setTestInstrumentationRunner(INSTRUMENTATION_RUNNER);
-
-        library.sourceSets.androidTest {
-            root "tests"
-            java.srcDir "tests/src"
-            res.srcDir "tests/res"
-            manifest.srcFile "tests/AndroidManifest.xml"
+            // Set test related options.
+            testInstrumentationRunner INSTRUMENTATION_RUNNER
         }
 
-        // Set compile options
-        library.getCompileOptions().setSourceCompatibility(JavaVersion.VERSION_1_7);
-        library.getCompileOptions().setTargetCompatibility(JavaVersion.VERSION_1_7);
+        // We use a non-standard test directory structure.
+        library.sourceSets.androidTest {
+            root 'tests'
+            java.srcDir 'tests/src'
+            res.srcDir 'tests/res'
+            manifest.srcFile 'tests/AndroidManifest.xml'
+        }
+
+        // Always lint check NewApi as fatal.
+        library.lintOptions {
+            abortOnError true
+            ignoreWarnings true
+
+            // Write output directly to the console (and nowhere else).
+            textOutput 'stderr'
+            textReport true
+            htmlReport false
+            xmlReport false
+
+            // Format output for convenience.
+            explainIssues true
+            noLines false
+            quiet true
+
+            // Always fail on NewApi.
+            error 'NewApi'
+        }
+
+        // Library projects don't run lint by default, so set up dependency.
+        project.tasks.release.dependsOn project.tasks.lint
+
+        // Java 8 is only fully supported on API 24+ and not all Java 8 features are binary
+        // compatible with API < 24, so use Java 7 for both source AND target.
+        library.compileOptions {
+            sourceCompatibility JavaVersion.VERSION_1_7
+            targetCompatibility JavaVersion.VERSION_1_7
+        }
 
         // Create sources jar for release builds
         library.getLibraryVariants().all(new Action<LibraryVariant>() {
@@ -85,7 +113,7 @@
             }
         });
 
-        // Set uploadArchives options
+        // Set uploadArchives options.
         Upload uploadTask = (Upload) project.getTasks().getByName("uploadArchives");
         project.afterEvaluate {
             uploadTask.repositories {
diff --git a/core-ui/java/android/support/v4/widget/SwipeRefreshLayout.java b/core-ui/java/android/support/v4/widget/SwipeRefreshLayout.java
index 8ccbe95..5b14129 100644
--- a/core-ui/java/android/support/v4/widget/SwipeRefreshLayout.java
+++ b/core-ui/java/android/support/v4/widget/SwipeRefreshLayout.java
@@ -176,7 +176,6 @@
         public void onAnimationRepeat(Animation animation) {
         }
 
-        @SuppressLint("NewApi")
         @Override
         public void onAnimationEnd(Animation animation) {
             if (mRefreshing) {
@@ -223,7 +222,6 @@
         reset();
     }
 
-    @SuppressLint("NewApi")
     private void setColorViewAlpha(int targetAlpha) {
         mCircleView.getBackground().setAlpha(targetAlpha);
         mProgress.setAlpha(targetAlpha);
@@ -417,7 +415,6 @@
         }
     }
 
-    @SuppressLint("NewApi")
     private void startScaleUpAnimation(AnimationListener listener) {
         mCircleView.setVisibility(View.VISIBLE);
         if (android.os.Build.VERSION.SDK_INT >= 11) {
@@ -475,10 +472,12 @@
         mCircleView.startAnimation(mScaleDownAnimation);
     }
 
+    @SuppressLint("NewApi")
     private void startProgressAlphaStartAnimation() {
         mAlphaStartAnimation = startAlphaAnimation(mProgress.getAlpha(), STARTING_PROGRESS_ALPHA);
     }
 
+    @SuppressLint("NewApi")
     private void startProgressAlphaMaxAnimation() {
         mAlphaMaxAnimation = startAlphaAnimation(mProgress.getAlpha(), MAX_ALPHA);
     }
@@ -1060,7 +1059,6 @@
         return true;
     }
 
-    @SuppressLint("NewApi")
     private void startDragging(float y) {
         final float yDiff = y - mInitialDownY;
         if (yDiff > mTouchSlop && !mIsBeingDragged) {
@@ -1130,7 +1128,6 @@
         }
     };
 
-    @SuppressLint("NewApi")
     private void startScaleDownReturnToStartAnimation(int from,
             Animation.AnimationListener listener) {
         mFrom = from;
diff --git a/gradlew b/gradlew
index 30aa96f..014f353 100755
--- a/gradlew
+++ b/gradlew
@@ -6,14 +6,6 @@
 ##
 ##############################################################################
 
-# Pick the correct fullsdk for this OS.
-if [ "$os" = "Darwin" ]; then
-    plat="darwin"
-else
-    plat="linux"
-fi
-DEFAULT_JVM_OPTS="-DLINT_API_DATABASE=../../prebuilts/fullsdk-$plat/platform-tools/api/api-versions.xml"
-
 # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
 
 APP_NAME="Gradle"
@@ -69,6 +61,14 @@
 
 CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 
+# Pick the correct fullsdk for this OS.
+if [ "$os" = "Darwin" ]; then
+    plat="darwin"
+else
+    plat="linux"
+fi
+DEFAULT_JVM_OPTS="-DLINT_API_DATABASE=$APP_HOME/../../prebuilts/fullsdk-$plat/platform-tools/api/api-versions.xml"
+
 # Determine the Java command to use to start the JVM.
 if [ -n "$JAVA_HOME" ] ; then
     if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
diff --git a/media-compat/api26/android/support/v4/media/session/MediaControllerCompatApi26.java b/media-compat/api26/android/support/v4/media/session/MediaControllerCompatApi26.java
index b2c4ac0..bf2ca60 100644
--- a/media-compat/api26/android/support/v4/media/session/MediaControllerCompatApi26.java
+++ b/media-compat/api26/android/support/v4/media/session/MediaControllerCompatApi26.java
@@ -16,11 +16,13 @@
 
 package android.support.v4.media.session;
 
+import android.annotation.TargetApi;
 import android.media.session.MediaController;
 
+@TargetApi(26)
 class MediaControllerCompatApi26 {
     public static Object createCallback(Callback callback) {
-        return new CallbackProxy<Callback>(callback);
+        return new CallbackProxy<>(callback);
     }
 
     public static int getRepeatMode(Object controllerObj) {
diff --git a/media-compat/api26/android/support/v4/media/session/MediaSessionCompatApi26.java b/media-compat/api26/android/support/v4/media/session/MediaSessionCompatApi26.java
index 80c5fd0..6d7ba4f 100644
--- a/media-compat/api26/android/support/v4/media/session/MediaSessionCompatApi26.java
+++ b/media-compat/api26/android/support/v4/media/session/MediaSessionCompatApi26.java
@@ -17,7 +17,9 @@
 package android.support.v4.media.session;
 
 import android.media.session.MediaSession;
+import android.support.annotation.RequiresApi;
 
+@RequiresApi(26)
 class MediaSessionCompatApi26 {
 
     public static Object createCallback(Callback callback) {
diff --git a/v17/preference-leanback/src/android/support/v17/preference/LeanbackListPreferenceDialogFragment.java b/v17/preference-leanback/src/android/support/v17/preference/LeanbackListPreferenceDialogFragment.java
index 6ab3999..c9837de 100644
--- a/v17/preference-leanback/src/android/support/v17/preference/LeanbackListPreferenceDialogFragment.java
+++ b/v17/preference-leanback/src/android/support/v17/preference/LeanbackListPreferenceDialogFragment.java
@@ -21,11 +21,11 @@
 import android.support.annotation.Nullable;
 import android.support.v14.preference.MultiSelectListPreference;
 import android.support.v17.leanback.widget.VerticalGridView;
+import android.support.v4.util.ArraySet;
 import android.support.v7.preference.DialogPreference;
 import android.support.v7.preference.ListPreference;
 import android.support.v7.widget.RecyclerView;
 import android.text.TextUtils;
-import android.util.ArraySet;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplBase.java b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplBase.java
index 2ccf149..753dbd2 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplBase.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplBase.java
@@ -19,7 +19,6 @@
 import android.app.Activity;
 import android.content.Context;
 import android.content.res.Resources;
-import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.os.Bundle;
@@ -29,7 +28,6 @@
 import android.support.v7.view.SupportMenuInflater;
 import android.support.v7.view.WindowCallbackWrapper;
 import android.support.v7.view.menu.MenuBuilder;
-import android.support.v7.widget.AppCompatDrawableManager;
 import android.support.v7.widget.TintTypedArray;
 import android.view.KeyEvent;
 import android.view.Menu;
@@ -37,7 +35,7 @@
 import android.view.View;
 import android.view.Window;
 
-@RequiresApi(9)
+@RequiresApi(14)
 abstract class AppCompatDelegateImplBase extends AppCompatDelegate {
 
     static final boolean DEBUG = false;
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV11.java b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV11.java
index 736b160..3aa7f3f 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV11.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV11.java
@@ -22,7 +22,7 @@
 import android.view.View;
 import android.view.Window;
 
-@RequiresApi(11)
+@RequiresApi(14)
 class AppCompatDelegateImplV11 extends AppCompatDelegateImplV9 {
 
     AppCompatDelegateImplV11(Context context, Window window, AppCompatCallback callback) {
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV9.java b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV9.java
index 64aa23b..ccb1c16 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV9.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV9.java
@@ -91,7 +91,7 @@
 
 import org.xmlpull.v1.XmlPullParser;
 
-@RequiresApi(9)
+@RequiresApi(14)
 class AppCompatDelegateImplV9 extends AppCompatDelegateImplBase
         implements MenuBuilder.Callback, LayoutInflater.Factory2 {
 
diff --git a/v7/appcompat/src/android/support/v7/app/ResourcesFlusher.java b/v7/appcompat/src/android/support/v7/app/ResourcesFlusher.java
index ad23092..ebfc7cb 100644
--- a/v7/appcompat/src/android/support/v7/app/ResourcesFlusher.java
+++ b/v7/appcompat/src/android/support/v7/app/ResourcesFlusher.java
@@ -16,6 +16,7 @@
 
 package android.support.v7.app;
 
+import android.annotation.TargetApi;
 import android.content.res.Resources;
 import android.os.Build;
 import android.support.annotation.NonNull;
@@ -41,17 +42,17 @@
     private static boolean sResourcesImplFieldFetched;
 
     static boolean flush(@NonNull final Resources resources) {
-        final int sdk = Build.VERSION.SDK_INT;
-        if (sdk >= 24) {
+        if (Build.VERSION.SDK_INT >= 24) {
             return flushNougats(resources);
-        } else if (sdk >= 23) {
+        } else if (Build.VERSION.SDK_INT >= 23) {
             return flushMarshmallows(resources);
-        } else if (sdk >= 21) {
+        } else if (Build.VERSION.SDK_INT >= 21) {
             return flushLollipops(resources);
         }
         return false;
     }
 
+    @TargetApi(21)
     private static boolean flushLollipops(@NonNull final Resources resources) {
         if (!sDrawableCacheFieldFetched) {
             try {
@@ -77,6 +78,7 @@
         return false;
     }
 
+    @TargetApi(23)
     private static boolean flushMarshmallows(@NonNull final Resources resources) {
         if (!sDrawableCacheFieldFetched) {
             try {
@@ -105,6 +107,7 @@
         return drawableCache != null && flushThemedResourcesCache(drawableCache);
     }
 
+    @TargetApi(24)
     private static boolean flushNougats(@NonNull final Resources resources) {
         if (!sResourcesImplFieldFetched) {
             try {
@@ -155,6 +158,7 @@
         return drawableCache != null && flushThemedResourcesCache(drawableCache);
     }
 
+    @TargetApi(16)
     private static boolean flushThemedResourcesCache(@NonNull final Object cache) {
         if (!sThemedResourceCacheClazzFetched) {
             try {