Merge "Require lint when building release target"
diff --git a/compat/api26/android/support/v4/content/pm/ShortcutManagerCompatApi26.java b/compat/api26/android/support/v4/content/pm/ShortcutManagerCompatApi26.java
deleted file mode 100644
index 692d629..0000000
--- a/compat/api26/android/support/v4/content/pm/ShortcutManagerCompatApi26.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * Copyright (C) 2017 The Android Open Source Project
- *
- * 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 android.support.v4.content.pm;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentSender;
-import android.content.pm.ShortcutManager;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.annotation.RequiresApi;
-
-@RequiresApi(26)
-class ShortcutManagerCompatApi26 {
-
-    public static boolean isRequestPinShortcutSupported(Context context) {
-        return context.getSystemService(ShortcutManager.class).isRequestPinShortcutSupported();
-    }
-
-    public static boolean requestPinShortcut(final Context context,
-            @NonNull ShortcutInfoCompat shortcut, @Nullable final IntentSender callback) {
-        return context.getSystemService(ShortcutManager.class).requestPinShortcut(
-                shortcut.toShortcutInfo(), callback);
-    }
-
-    @Nullable
-    public static Intent createShortcutResultIntent(Context context,
-            @NonNull ShortcutInfoCompat shortcut) {
-        return context.getSystemService(ShortcutManager.class)
-                .createShortcutResultIntent(shortcut.toShortcutInfo());
-    }
-}
diff --git a/compat/java/android/support/v4/content/pm/ShortcutManagerCompat.java b/compat/java/android/support/v4/content/pm/ShortcutManagerCompat.java
index 48d93ca..2261e86 100644
--- a/compat/java/android/support/v4/content/pm/ShortcutManagerCompat.java
+++ b/compat/java/android/support/v4/content/pm/ShortcutManagerCompat.java
@@ -23,6 +23,7 @@
 import android.content.IntentSender;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.content.pm.ShortcutManager;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.annotation.VisibleForTesting;
@@ -47,7 +48,7 @@
      */
     public static boolean isRequestPinShortcutSupported(@NonNull Context context) {
         if (BuildCompat.isAtLeastO()) {
-            return ShortcutManagerCompatApi26.isRequestPinShortcutSupported(context);
+            return context.getSystemService(ShortcutManager.class).isRequestPinShortcutSupported();
         }
 
         if (ContextCompat.checkSelfPermission(context, INSTALL_SHORTCUT_PERMISSION)
@@ -84,7 +85,8 @@
     public static boolean requestPinShortcut(@NonNull final Context context,
             @NonNull ShortcutInfoCompat shortcut, @Nullable final IntentSender callback) {
         if (BuildCompat.isAtLeastO()) {
-            return ShortcutManagerCompatApi26.requestPinShortcut(context, shortcut, callback);
+            return context.getSystemService(ShortcutManager.class).requestPinShortcut(
+                    shortcut.toShortcutInfo(), callback);
         }
 
         if (!isRequestPinShortcutSupported(context)) {
@@ -127,7 +129,8 @@
             @NonNull ShortcutInfoCompat shortcut) {
         Intent result = null;
         if (BuildCompat.isAtLeastO()) {
-            result = ShortcutManagerCompatApi26.createShortcutResultIntent(context, shortcut);
+            result = context.getSystemService(ShortcutManager.class)
+                    .createShortcutResultIntent(shortcut.toShortcutInfo());
         }
         if (result == null) {
             result = new Intent();
diff --git a/core-ui/java/android/support/v4/view/AsyncLayoutInflater.java b/core-ui/java/android/support/v4/view/AsyncLayoutInflater.java
index e638d05..e194a50 100644
--- a/core-ui/java/android/support/v4/view/AsyncLayoutInflater.java
+++ b/core-ui/java/android/support/v4/view/AsyncLayoutInflater.java
@@ -169,28 +169,35 @@
         private ArrayBlockingQueue<InflateRequest> mQueue = new ArrayBlockingQueue<>(10);
         private SynchronizedPool<InflateRequest> mRequestPool = new SynchronizedPool<>(10);
 
+        // Extracted to its own method to ensure locals have a constrained liveness
+        // scope by the GC. This is needed to avoid keeping previous request references
+        // alive for an indeterminate amount of time, see b/33158143 for details
+        public void runInner() {
+            InflateRequest request;
+            try {
+                request = mQueue.take();
+            } catch (InterruptedException ex) {
+                // Odd, just continue
+                Log.w(TAG, ex);
+                return;
+            }
+
+            try {
+                request.view = request.inflater.mInflater.inflate(
+                        request.resid, request.parent, false);
+            } catch (RuntimeException ex) {
+                // Probably a Looper failure, retry on the UI thread
+                Log.w(TAG, "Failed to inflate resource in the background! Retrying on the UI"
+                        + " thread", ex);
+            }
+            Message.obtain(request.inflater.mHandler, 0, request)
+                    .sendToTarget();
+        }
+
         @Override
         public void run() {
             while (true) {
-                InflateRequest request;
-                try {
-                    request = mQueue.take();
-                } catch (InterruptedException ex) {
-                    // Odd, just continue
-                    Log.w(TAG, ex);
-                    continue;
-                }
-
-                try {
-                    request.view = request.inflater.mInflater.inflate(
-                            request.resid, request.parent, false);
-                } catch (RuntimeException ex) {
-                    // Probably a Looper failure, retry on the UI thread
-                    Log.w(TAG, "Failed to inflate resource in the background! Retrying on the UI"
-                            + " thread", ex);
-                }
-                Message.obtain(request.inflater.mHandler, 0, request)
-                        .sendToTarget();
+                runInner();
             }
         }
 
diff --git a/samples/SupportLeanbackDemos/res/values/themes.xml b/samples/SupportLeanbackDemos/res/values/themes.xml
index 58ae373..e2292b5 100644
--- a/samples/SupportLeanbackDemos/res/values/themes.xml
+++ b/samples/SupportLeanbackDemos/res/values/themes.xml
@@ -14,7 +14,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools" >
     <style name="Theme.Example.Leanback" parent="Theme.Leanback">
     </style>
     <style name="Theme.Example.Leanback.Browse" parent="Theme.Leanback.Browse">
@@ -45,8 +45,8 @@
         <item name="android:windowIsTranslucent">true</item>
         <item name="android:windowBackground">@android:color/transparent</item>
         <item name="android:backgroundDimEnabled">true</item>
-        <item name="android:colorPrimary">@color/settings_background</item>
-        <item name="android:colorAccent">?attr/defaultBrandColor</item>
+        <item name="android:colorPrimary" tools:targetApi="21" >@color/settings_background</item>
+        <item name="android:colorAccent" tools:targetApi="21">?attr/defaultBrandColor</item>
     </style>
     <style name="Theme.Example.Leanback.Onboarding" parent="Theme.Leanback.Onboarding">
         <item name="onboardingLogoStyle">@style/Widget.Example.Leanback.OnboardingLogoStyle</item>
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackFragment.java
index a29a995..91ecd62 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackFragment.java
@@ -17,6 +17,7 @@
 package com.example.android.leanback;
 
 import android.content.Context;
+import android.os.Build;
 import android.os.Bundle;
 import android.support.v17.leanback.app.PlaybackFragmentGlueHost;
 import android.support.v17.leanback.widget.Action;
@@ -86,7 +87,9 @@
             @Override
             public void onActionClicked(Action action) {
                 if (action.getId() == R.id.lb_control_picture_in_picture) {
-                    getActivity().enterPictureInPictureMode();
+                    if (Build.VERSION.SDK_INT >= 24) {
+                        getActivity().enterPictureInPictureMode();
+                    }
                     return;
                 }
                 super.onActionClicked(action);
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackSupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackSupportFragment.java
index 6d2fa51..64effab 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackSupportFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackSupportFragment.java
@@ -20,6 +20,7 @@
 package com.example.android.leanback;
 
 import android.content.Context;
+import android.os.Build;
 import android.os.Bundle;
 import android.support.v17.leanback.app.PlaybackSupportFragmentGlueHost;
 import android.support.v17.leanback.widget.Action;
@@ -89,7 +90,9 @@
             @Override
             public void onActionClicked(Action action) {
                 if (action.getId() == R.id.lb_control_picture_in_picture) {
-                    getActivity().enterPictureInPictureMode();
+                    if (Build.VERSION.SDK_INT >= 24) {
+                        getActivity().enterPictureInPictureMode();
+                    }
                     return;
                 }
                 super.onActionClicked(action);