Bug 1385464 - Start using support library v. 26; r=nalexander
authorPetru Lingurar <petru.lingurar@softvision.ro>
Fri, 13 Jul 2018 17:16:37 +0300
changeset 818903 c2b1f1b52866d2c58f5e23fe2df97c9127ebcacf
parent 818902 793a1a3ba37270e16e4a5493b9322bb37fed51bc
child 818904 63239b786a26cfd8778106916eb21ddf4fa67bed
push id116388
push userrwood@mozilla.com
push dateMon, 16 Jul 2018 19:48:57 +0000
reviewersnalexander
bugs1385464
milestone63.0a1
Bug 1385464 - Start using support library v. 26; r=nalexander This patch also: Resolves missing resources and api changes - LeanplumActionBarActivity was removed because Support Library 26 deprecated ActionBarActivity. Class was already not in use. - CustomTabsService added two new methods which we need to override. Tested to make sure that previous functionality was maintained but with the addition of the two new methods maybe that feature could be improved. - For checking layout direction we'll use our own new method from ViewUtil which mimics what the now restricted method from the support library would do. - Upgraded to use AppCompatResources#getDrawable(..) in place of the now restricted AppCompatDrawableManager.get().getDrawable(..). Resolves obscure leaks and crashes after the upgrade - LoaderManager.destroyLoader(..) was added before the existing call to LoaderManager.restartLoader(..) to prevent potential Cursor leaks - Disable website suggestions depending on the address bar inputs when running in automation to avoid Robocop tests failing (they were entering serially maybe 100 characters in <5 ms which created around that many new Threads, operation that could cause the Executor to throw a RejectedExecutionException) At the moment this functionality is not covered by tests anyway and it was the only fix I could find that would not involve changing the whole implemenation for address bar suggestions, implementation which in the real world works ok. MozReview-Commit-ID: 2fX1SBHiSh0
build.gradle
mobile/android/app/src/main/res/layout/bookmark_add_folder.xml
mobile/android/app/src/main/res/layout/bookmark_edit_with_full_page.xml
mobile/android/app/src/main/res/layout/bookmark_folder_select.xml
mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
mobile/android/base/java/org/mozilla/gecko/customtabs/GeckoCustomTabsService.java
mobile/android/base/java/org/mozilla/gecko/home/SearchLoader.java
mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java
mobile/android/base/java/org/mozilla/gecko/tabs/TabStripDividerItem.java
mobile/android/base/java/org/mozilla/gecko/tabs/TabStripView.java
mobile/android/base/java/org/mozilla/gecko/tabs/TabsLayoutItemView.java
mobile/android/base/java/org/mozilla/gecko/util/ResourceDrawableUtils.java
mobile/android/base/java/org/mozilla/gecko/util/ViewUtil.java
mobile/android/base/java/org/mozilla/gecko/widget/DefaultItemAnimatorBase.java
mobile/android/base/java/org/mozilla/gecko/widget/GridSpacingDecoration.java
mobile/android/config/proguard/proguard-leanplum.cfg
mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/components/ToolbarComponent.java
mobile/android/thirdparty/com/leanplum/activities/LeanplumActionBarActivity.java
--- a/build.gradle
+++ b/build.gradle
@@ -46,17 +46,17 @@ buildscript {
         }
         // For in tree plugins.
         maven {
             url "file://${gradle.mozconfig.topsrcdir}/mobile/android/gradle/m2repo"
         }
     }
 
     ext.kotlin_version = '1.2.41'
-    ext.support_library_version = '23.4.0'
+    ext.support_library_version = '26.1.0'
 
     if (gradle.mozconfig.substs.MOZ_ANDROID_GOOGLE_PLAY_SERVICES) {
         ext.google_play_services_version = '8.4.0'
     }
 
     dependencies {
         classpath 'com.android.tools.build:gradle:3.0.1'
         classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.8.2'
--- a/mobile/android/app/src/main/res/layout/bookmark_add_folder.xml
+++ b/mobile/android/app/src/main/res/layout/bookmark_add_folder.xml
@@ -13,17 +13,17 @@
     android:background="@android:color/white">
 
     <android.support.v7.widget.Toolbar
         android:id="@+id/toolbar"
         android:layout_width="match_parent"
         android:layout_height="?actionBarSize"
         android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
         android:background="@color/text_and_tabs_tray_grey"
-        app:navigationIcon="@drawable/abc_ic_clear_mtrl_alpha"
+        app:navigationIcon="@drawable/abc_ic_clear_material"
         app:subtitleTextColor="@android:color/white"
         app:title="@string/bookmark_add_folder"
         app:titleTextColor="@android:color/white" />
 
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="0dp"
         android:layout_weight="1"
--- a/mobile/android/app/src/main/res/layout/bookmark_edit_with_full_page.xml
+++ b/mobile/android/app/src/main/res/layout/bookmark_edit_with_full_page.xml
@@ -13,17 +13,17 @@
 
     <android.support.v7.widget.Toolbar
         android:id="@+id/toolbar"
         android:layout_width="match_parent"
         android:layout_height="56dp"
         android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
         android:background="@color/text_and_tabs_tray_grey"
         android:minHeight="?actionBarSize"
-        app:navigationIcon="@drawable/abc_ic_clear_mtrl_alpha"
+        app:navigationIcon="@drawable/abc_ic_clear_material"
         app:subtitleTextColor="@android:color/white"
         app:titleTextColor="@android:color/white" />
 
     <ScrollView
         android:layout_width="match_parent"
         android:layout_height="match_parent">
 
         <LinearLayout
--- a/mobile/android/app/src/main/res/layout/bookmark_folder_select.xml
+++ b/mobile/android/app/src/main/res/layout/bookmark_folder_select.xml
@@ -12,17 +12,17 @@
     android:background="@android:color/white">
 
     <android.support.v7.widget.Toolbar
         android:id="@+id/toolbar"
         android:layout_width="match_parent"
         android:layout_height="?actionBarSize"
         android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
         android:background="@color/text_and_tabs_tray_grey"
-        app:navigationIcon="@drawable/abc_ic_ab_back_mtrl_am_alpha"
+        app:navigationIcon="@drawable/abc_ic_ab_back_material"
         app:subtitleTextColor="@android:color/white"
         app:title="@string/bookmark_select_folder" />
 
     <android.support.v7.widget.RecyclerView
         android:id="@+id/folder_recycler_view"
         android:layout_width="match_parent"
         android:layout_height="0dp"
         android:layout_weight="1"
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -1326,22 +1326,27 @@ public class BrowserApp extends GeckoApp
 
         mBrowserToolbar.setOnDismissListener(new BrowserToolbar.OnDismissListener() {
             @Override
             public void onDismiss() {
                 mBrowserToolbar.cancelEdit();
             }
         });
 
-        mBrowserToolbar.setOnFilterListener(new BrowserToolbar.OnFilterListener() {
-            @Override
-            public void onFilter(String searchText, AutocompleteHandler handler) {
-                filterEditingMode(searchText, handler);
-            }
-        });
+        // Website suggestions for address bar inputs should not be enabled when running in automation.
+        // After the upgrade to support library v.26 it could fail otherwise unrelated Robocop tests
+        // See https://bugzilla.mozilla.org/show_bug.cgi?id=1385464#c3
+        if (!isInAutomation) {
+            mBrowserToolbar.setOnFilterListener(new BrowserToolbar.OnFilterListener() {
+                @Override
+                public void onFilter(String searchText, AutocompleteHandler handler) {
+                    filterEditingMode(searchText, handler);
+                }
+            });
+        }
 
         mBrowserToolbar.setOnFocusChangeListener(new View.OnFocusChangeListener() {
             @Override
             public void onFocusChange(View v, boolean hasFocus) {
                 if (isHomePagerVisible()) {
                     mHomeScreen.onToolbarFocusChange(hasFocus);
                 }
             }
--- a/mobile/android/base/java/org/mozilla/gecko/customtabs/GeckoCustomTabsService.java
+++ b/mobile/android/base/java/org/mozilla/gecko/customtabs/GeckoCustomTabsService.java
@@ -98,9 +98,19 @@ public class GeckoCustomTabsService exte
     }
 
     @Override
     protected Bundle extraCommand(String commandName, Bundle bundle) {
         Log.v(LOGTAG, "extraCommand()");
 
         return null;
     }
+
+    @Override
+    protected boolean requestPostMessageChannel(CustomTabsSessionToken sessionToken, Uri postMessageOrigin) {
+        return false;
+    }
+
+    @Override
+    protected int postMessage(CustomTabsSessionToken sessionToken, String message, Bundle extras) {
+        return RESULT_FAILURE_DISALLOWED;
+    }
 }
--- a/mobile/android/base/java/org/mozilla/gecko/home/SearchLoader.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/SearchLoader.java
@@ -67,16 +67,17 @@ class SearchLoader {
     public static void restart(LoaderManager manager, int loaderId,
                                LoaderCallbacks<Cursor> callbacks, String searchTerm) {
         restart(manager, loaderId, callbacks, searchTerm, EnumSet.noneOf(FilterFlags.class));
     }
 
     public static void restart(LoaderManager manager, int loaderId,
                                LoaderCallbacks<Cursor> callbacks, String searchTerm,
                                EnumSet<FilterFlags> flags) {
+        manager.destroyLoader(loaderId);
         final Bundle args = createArgs(searchTerm, flags);
         manager.restartLoader(loaderId, args, callbacks);
     }
 
     public static class SearchCursorLoader extends SimpleCursorLoader {
         private static final String TELEMETRY_HISTOGRAM_LOAD_CURSOR = "FENNEC_SEARCH_LOADER_TIME_MS";
 
         // Max number of search results.
--- a/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java
+++ b/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java
@@ -228,17 +228,17 @@ public class GeckoPreferences
         }
     }
 
     private void updateHomeAsUpIndicator() {
         final ActionBar actionBar = getSupportActionBar();
         if (actionBar == null) {
             return;
         }
-        actionBar.setHomeAsUpIndicator(android.support.v7.appcompat.R.drawable.abc_ic_ab_back_mtrl_am_alpha);
+        actionBar.setHomeAsUpIndicator(android.support.v7.appcompat.R.drawable.abc_ic_ab_back_material);
     }
 
     /**
      * We only call this method for pre-HC versions of Android.
      */
     private void updateTitleForPrefsResource(int res) {
         // At present we only need to do this for non-leaf prefs views
         // and the locale switcher itself.
--- a/mobile/android/base/java/org/mozilla/gecko/tabs/TabStripDividerItem.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabs/TabStripDividerItem.java
@@ -1,26 +1,26 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.tabs;
 
-import org.mozilla.gecko.R;
-
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.support.v4.content.ContextCompat;
 import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.ViewUtils;
 import android.view.View;
 
+import org.mozilla.gecko.R;
+import org.mozilla.gecko.util.ViewUtil;
+
 class TabStripDividerItem extends RecyclerView.ItemDecoration {
     private final int margin;
     private final int dividerWidth;
     private final int dividerHeight;
     private final int dividerPaddingBottom;
     private final Paint dividerPaint;
 
     TabStripDividerItem(Context context) {
@@ -34,17 +34,17 @@ class TabStripDividerItem extends Recycl
         dividerPaint.setStyle(Paint.Style.FILL_AND_STROKE);
     }
 
     /**
      * Return whether a divider should be drawn on the left side of the tab represented by
      * {@code view}.
      */
     private static boolean drawLeftDividerForView(View view, RecyclerView parent) {
-        final boolean isLTR = !ViewUtils.isLayoutRtl(parent);
+        final boolean isLTR = !ViewUtil.isLayoutRtl(parent);
         final int position = parent.getChildAdapterPosition(view);
         // No left divider if this is the leftmost tab or this tab is currently pressed.
         final boolean isLeftmostTab = isLTR ? position == 0 : position == parent.getAdapter().getItemCount() - 1;
         if (isLeftmostTab || view.isPressed()) {
             return false;
         }
 
         final int selectedPosition = ((TabStripView) parent).getPositionForSelectedTab();
@@ -66,17 +66,17 @@ class TabStripDividerItem extends Recycl
     }
 
     @Override
     public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
         final int position = parent.getChildAdapterPosition(view);
 
         // RTL positions start from the right, but offsets are still LTR since view is LTR.
         final int leftOffset, rightOffset;
-        if (ViewUtils.isLayoutRtl(parent)) {
+        if (ViewUtil.isLayoutRtl(parent)) {
             leftOffset = position == parent.getAdapter().getItemCount() - 1 ? 0 : margin;
             rightOffset = position == 0 ? 0 : margin;
         } else {
             leftOffset = position == 0 ? 0 : margin;
             rightOffset = position == parent.getAdapter().getItemCount() - 1 ? 0 : margin;
         }
 
         outRect.set(leftOffset, 0, rightOffset, 0);
--- a/mobile/android/base/java/org/mozilla/gecko/tabs/TabStripView.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabs/TabStripView.java
@@ -1,38 +1,38 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.tabs;
 
-import org.mozilla.gecko.R;
-import org.mozilla.gecko.Tab;
-import org.mozilla.gecko.Tabs;
-import org.mozilla.gecko.util.ThreadUtils;
-
 import android.animation.Animator;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.LinearGradient;
 import android.graphics.Paint;
 import android.graphics.Shader;
 import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.ViewUtils;
 import android.support.v7.widget.helper.ItemTouchHelper;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewTreeObserver;
 import android.view.animation.DecelerateInterpolator;
 
+import org.mozilla.gecko.R;
+import org.mozilla.gecko.Tab;
+import org.mozilla.gecko.Tabs;
+import org.mozilla.gecko.util.ThreadUtils;
+import org.mozilla.gecko.util.ViewUtil;
+
 import java.util.ArrayList;
 import java.util.List;
 
 public class TabStripView extends RecyclerView
                           implements TabsTouchHelperCallback.DragListener {
     private static final int ANIM_TIME_MS = 200;
     private static final DecelerateInterpolator ANIM_INTERPOLATOR = new DecelerateInterpolator();
 
@@ -221,17 +221,17 @@ public class TabStripView extends Recycl
         if (w == oldw) {
             return;
         }
 
         // Gradient argb color stops.
         final int transparent = 0x0;
         final int inBetween = 0x11292C29;
         final int darkest = 0xDD292C29;
-        if (ViewUtils.isLayoutRtl(this)) {
+        if (ViewUtil.isLayoutRtl(this)) {
             fadingEdgePaint.setShader(new LinearGradient(0, 0, fadingEdgeSize, 0,
                     new int[] { darkest, inBetween, transparent },
                     new float[] { 0, 0.6f, 1.0f }, Shader.TileMode.CLAMP));
         } else {
             fadingEdgePaint.setShader(new LinearGradient(w - fadingEdgeSize, 0, w, 0,
                     new int[] { transparent, inBetween, darkest },
                     new float[] { 0, 0.4f, 1.0f }, Shader.TileMode.CLAMP));
         }
@@ -264,17 +264,17 @@ public class TabStripView extends Recycl
 
             return Math.max(0.0f, Math.min(strength, 1.0f));
         }
     }
 
     @Override
     public void draw(Canvas canvas) {
         super.draw(canvas);
-        final boolean isLTR = !ViewUtils.isLayoutRtl(this);
+        final boolean isLTR = !ViewUtil.isLayoutRtl(this);
         final float strength = getFadingEdgeStrength(isLTR);
         if (strength > 0.0f) {
             if (isLTR) {
                 final int w = getWidth();
                 canvas.drawRect(w - fadingEdgeSize, getTop(), w, getBottom(), fadingEdgePaint);
             } else {
                 canvas.drawRect(0, getTop(), fadingEdgeSize, getBottom(), fadingEdgePaint);
             }
--- a/mobile/android/base/java/org/mozilla/gecko/tabs/TabsLayoutItemView.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabs/TabsLayoutItemView.java
@@ -1,40 +1,40 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.tabs;
 
-import org.mozilla.gecko.R;
-import org.mozilla.gecko.Tab;
-import org.mozilla.gecko.Tabs;
-import org.mozilla.gecko.icons.IconResponse;
-import org.mozilla.gecko.icons.Icons;
-import org.mozilla.gecko.widget.FaviconView;
-import org.mozilla.gecko.widget.HoverDelegateWithReset;
-import org.mozilla.gecko.widget.TabThumbnailWrapper;
-import org.mozilla.gecko.widget.TouchDelegateWithReset;
-import org.mozilla.gecko.widget.themed.ThemedRelativeLayout;
-
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
-import android.support.v7.widget.ViewUtils;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.TypedValue;
 import android.view.MotionEvent;
 import android.view.View;
 import android.widget.Checkable;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import org.mozilla.gecko.R;
+import org.mozilla.gecko.Tab;
+import org.mozilla.gecko.Tabs;
+import org.mozilla.gecko.icons.IconResponse;
+import org.mozilla.gecko.icons.Icons;
+import org.mozilla.gecko.util.ViewUtil;
+import org.mozilla.gecko.widget.FaviconView;
+import org.mozilla.gecko.widget.HoverDelegateWithReset;
+import org.mozilla.gecko.widget.TabThumbnailWrapper;
+import org.mozilla.gecko.widget.TouchDelegateWithReset;
+import org.mozilla.gecko.widget.themed.ThemedRelativeLayout;
+
 import java.util.concurrent.Future;
 
 public class TabsLayoutItemView extends LinearLayout
                                 implements Checkable {
     private static final String LOGTAG = "Gecko" + TabsLayoutItemView.class.getSimpleName();
     private static final int[] STATE_CHECKED = { android.R.attr.state_checked };
     private boolean mChecked;
 
@@ -124,17 +124,17 @@ public class TabsLayoutItemView extends 
 
                 setTouchDelegate(new TouchDelegateWithReset(hitRect, mCloseButton));
                 setHoverDelegate(new HoverDelegateWithReset(hitRect, mCloseButton));
             }
         });
     }
 
     private Rect getHitRectRelatively(int targetHitArea) {
-        final boolean isRtl = ViewUtils.isLayoutRtl(this);
+        final boolean isRtl = ViewUtil.isLayoutRtl(this);
         final Rect hitRect = new Rect();
         hitRect.top = 0;
         hitRect.right = isRtl ? targetHitArea : getWidth();
         hitRect.left = isRtl ? 0 : getWidth() - targetHitArea;
         hitRect.bottom = targetHitArea;
         return hitRect;
     }
 
--- a/mobile/android/base/java/org/mozilla/gecko/util/ResourceDrawableUtils.java
+++ b/mobile/android/base/java/org/mozilla/gecko/util/ResourceDrawableUtils.java
@@ -5,38 +5,32 @@
 package org.mozilla.gecko.util;
 
 import android.content.Context;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.support.annotation.DrawableRes;
 import android.support.annotation.NonNull;
-import android.support.v7.widget.AppCompatDrawableManager;
+import android.support.v7.content.res.AppCompatResources;
 import android.text.TextUtils;
 import android.util.Log;
 
-import org.mozilla.gecko.util.GeckoJarReader;
-import org.mozilla.gecko.util.ThreadUtils;
-import org.mozilla.gecko.util.UIAsyncTask;
-
 import java.io.InputStream;
 import java.net.URL;
 
 import static org.mozilla.gecko.util.BitmapUtils.getBitmapFromDataURI;
 import static org.mozilla.gecko.util.BitmapUtils.getResource;
 
 public class ResourceDrawableUtils {
     private static final String LOGTAG = "ResourceDrawableUtils";
 
     public static Drawable getDrawable(@NonNull final Context context,
                                        @DrawableRes final int drawableID) {
-        // TODO: upgrade this call to use AppCompatResources when upgrading to support library >= 24.2
-        // https://developer.android.com/reference/android/support/v7/content/res/AppCompatResources.html#getDrawable(android.content.Context,%20int)
-        return AppCompatDrawableManager.get().getDrawable(context, drawableID);
+        return AppCompatResources.getDrawable(context, drawableID);
     }
 
     public interface BitmapLoader {
         public void onBitmapFound(Drawable d);
     }
 
     public static void runOnBitmapFoundOnUiThread(final BitmapLoader loader, final Drawable d) {
         if (ThreadUtils.isOnUiThread()) {
--- a/mobile/android/base/java/org/mozilla/gecko/util/ViewUtil.java
+++ b/mobile/android/base/java/org/mozilla/gecko/util/ViewUtil.java
@@ -190,9 +190,19 @@ public class ViewUtil {
     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
     private static void setTextDirectionRtlCompat17(TextView textView, boolean isRtl) {
         if (isRtl) {
             textView.setTextDirection(View.TEXT_DIRECTION_RTL);
         } else {
             textView.setTextDirection(View.TEXT_DIRECTION_LTR);
         }
     }
+
+    /**
+     * Get if the resolved layout direction is <em>right to left</em> or <em>left to right</em>.
+     * @param view View to get layout direction for
+     * @return <code>true</code> if the horizontal layout direction of this view is from <em>right to left</em><br>
+     *     <code>false</code> if the horizontal layout direction of this view is from <em>left to right</em>
+     */
+    public static boolean isLayoutRtl(final View view) {
+        return ViewCompat.getLayoutDirection(view) == ViewCompat.LAYOUT_DIRECTION_RTL;
+    }
 }
--- a/mobile/android/base/java/org/mozilla/gecko/widget/DefaultItemAnimatorBase.java
+++ b/mobile/android/base/java/org/mozilla/gecko/widget/DefaultItemAnimatorBase.java
@@ -1,17 +1,18 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.widget;
 
+import android.animation.TimeInterpolator;
+import android.animation.ValueAnimator;
 import android.support.annotation.NonNull;
-import android.support.v4.animation.AnimatorCompatHelper;
 import android.support.v4.view.ViewCompat;
 import android.support.v4.view.ViewPropertyAnimatorCompat;
 import android.support.v4.view.ViewPropertyAnimatorListener;
 import android.support.v7.widget.RecyclerView;
 import android.support.v7.widget.SimpleItemAnimator;
 import android.view.View;
 
 import java.util.ArrayList;
@@ -36,16 +37,18 @@ import java.util.List;
  *       values before resetting the current animation, so this class does not provide the reset
  *       service itself.</li>
  *   <li>{@link #resetViewProperties(View)} is used to reset a view any time an animation ends or
  *       gets canceled - you should redefine resetViewProperties if the version here doesn't reset
  *       all of the properties you're animating.</li>
  * </ul>
  */
 public class DefaultItemAnimatorBase extends SimpleItemAnimator {
+    private static TimeInterpolator defaultInterpolator;
+
     private List<RecyclerView.ViewHolder> pendingRemovals = new ArrayList<>();
     private List<RecyclerView.ViewHolder> pendingAdditions = new ArrayList<>();
     private List<MoveInfo> pendingMoves = new ArrayList<>();
     private List<ChangeInfo> pendingChanges = new ArrayList<>();
 
     private List<List<RecyclerView.ViewHolder>> additionsList = new ArrayList<>();
     private List<List<MoveInfo>> movesList = new ArrayList<>();
     private List<List<ChangeInfo>> changesList = new ArrayList<>();
@@ -476,17 +479,20 @@ public class DefaultItemAnimatorBase ext
                     additionsList.remove(i);
                 }
             }
         }
         dispatchFinishedWhenDone();
     }
 
     protected void resetAnimation(RecyclerView.ViewHolder holder) {
-        AnimatorCompatHelper.clearInterpolator(holder.itemView);
+        if (defaultInterpolator == null) {
+            defaultInterpolator = new ValueAnimator().getInterpolator();
+        }
+        holder.itemView.animate().setInterpolator(defaultInterpolator);
         endAnimation(holder);
     }
 
     @Override
     public boolean isRunning() {
         return (!pendingAdditions.isEmpty() ||
                 !pendingChanges.isEmpty() ||
                 !pendingMoves.isEmpty() ||
--- a/mobile/android/base/java/org/mozilla/gecko/widget/GridSpacingDecoration.java
+++ b/mobile/android/base/java/org/mozilla/gecko/widget/GridSpacingDecoration.java
@@ -3,19 +3,20 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.widget;
 
 import android.graphics.Rect;
 import android.support.v7.widget.GridLayoutManager;
 import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.ViewUtils;
 import android.view.View;
 
+import org.mozilla.gecko.util.ViewUtil;
+
 /**
  * An ItemDecoration for a GridLayoutManager that provides fixed spacing (but not fixed padding)
  * to create fixed sized items, with no spacing on the outer edges of the outer items.
  * <p>
  * So, for example, if there are 2 columns and the spacing is s, then the first column gets a right
  * padding of s/2 and the second column gets a left paddding of s/2.  If there are three columns
  * then the first column gets a right padding of 2s/3, the second column gets left and right
  * paddings of s/3, and the third column gets a left padding of 2s/3.
@@ -37,16 +38,16 @@ public class GridSpacingDecoration exten
             return;
         }
 
         final GridLayoutManager layoutManager = (GridLayoutManager) parent.getLayoutManager();
         final int spanCount = layoutManager.getSpanCount();
         // If we're RTL then column counts start from the right, but view is still LTR (i.e. offsets
         // are still LTR), so compute offsets using the LTR column position (also note that this
         // only works because offsets in a given column are the same for LTR and RTL layouts).
-        final int LTRColumn = ViewUtils.isLayoutRtl(parent) ? (spanCount - 1) - (position % spanCount) : position % spanCount;
+        final int LTRColumn = ViewUtil.isLayoutRtl(parent) ? (spanCount - 1) - (position % spanCount) : position % spanCount;
 
         final int columnLeftOffset = (int) (((float) LTRColumn / (float) spanCount) * horizontalSpacing);
         final int columnRightOffset = (int) (((float) (spanCount - (LTRColumn + 1)) / (float) spanCount) * horizontalSpacing);
 
         outRect.set(columnLeftOffset, verticalPadding, columnRightOffset, verticalPadding);
     }
 }
--- a/mobile/android/config/proguard/proguard-leanplum.cfg
+++ b/mobile/android/config/proguard/proguard-leanplum.cfg
@@ -333,16 +333,15 @@
 -keep class com.leanplum.utils.BitmapUtil { public private protected *; }
 
 -keep class com.leanplum.LocationManagerImplementation { *; }
 
 -keep class com.leanplum.messagetemplates.BaseMessageOptions { *; }
 
 #-dontwarn android.support.v7.**
 -keep class android.support.v7.app.AppCompatActivity
--keep class android.support.v7.app.ActionBarActivity
 #-keep interface android.support.v7.** { *; }
 
 -printmapping out.map
 -renamesourcefileattribute SourceFile
 -keepattributes SourceFile,LineNumberTable
 
 -optimizations !code/allocation/variable
--- a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/components/ToolbarComponent.java
+++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/components/ToolbarComponent.java
@@ -16,17 +16,16 @@ import org.mozilla.gecko.tests.helpers.N
 import org.mozilla.gecko.tests.helpers.WaitHelper;
 import org.mozilla.gecko.toolbar.PageActionLayout;
 import org.mozilla.gecko.toolbar.TabCounter;
 
 import android.net.Uri;
 import android.view.View;
 import android.widget.EditText;
 import android.widget.ImageButton;
-import android.widget.TextSwitcher;
 import android.widget.TextView;
 
 import com.robotium.solo.Condition;
 import com.robotium.solo.Solo;
 
 import java.net.IDN;
 
 /**
deleted file mode 100644
--- a/mobile/android/thirdparty/com/leanplum/activities/LeanplumActionBarActivity.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright 2013, Leanplum, Inc. All rights reserved.
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.leanplum.activities;
-
-import android.annotation.SuppressLint;
-import android.content.res.Resources;
-import android.support.v7.app.ActionBarActivity;
-
-import com.leanplum.Leanplum;
-import com.leanplum.LeanplumActivityHelper;
-
-@SuppressLint("Registered")
-@SuppressWarnings("deprecation")
-public class LeanplumActionBarActivity extends ActionBarActivity {
-  private LeanplumActivityHelper helper;
-
-  private LeanplumActivityHelper getHelper() {
-    if (helper == null) {
-      helper = new LeanplumActivityHelper(this);
-    }
-    return helper;
-  }
-
-  @Override
-  protected void onPause() {
-    super.onPause();
-    getHelper().onPause();
-  }
-
-  @Override
-  protected void onStop() {
-    super.onStop();
-    getHelper().onStop();
-  }
-
-  @Override
-  protected void onResume() {
-    super.onResume();
-    getHelper().onResume();
-  }
-
-  @Override
-  public Resources getResources() {
-    if (Leanplum.isTestModeEnabled() || !Leanplum.isResourceSyncingEnabled()) {
-      return super.getResources();
-    }
-    return getHelper().getLeanplumResources(super.getResources());
-  }
-
-  @Override
-  public void setContentView(final int layoutResID) {
-    if (Leanplum.isTestModeEnabled() || !Leanplum.isResourceSyncingEnabled()) {
-      super.setContentView(layoutResID);
-      return;
-    }
-    getHelper().setContentView(layoutResID);
-  }
-}