Backed out 6 changesets (bug 1366672) for android linting failures a=backout
authorWes Kocher <wkocher@mozilla.com>
Tue, 15 Aug 2017 11:38:08 -0700
changeset 647051 cfef5aec8f82a572acaafc56e50d7125de7076e1
parent 647050 a9a6206bf9380fe37ee6e3a5d7483dcb1c184d2d
child 647052 33a59196dc7001ce459f94de87733f213064d5a7
push id74288
push userhikezoe@mozilla.com
push dateWed, 16 Aug 2017 00:19:57 +0000
reviewersbackout
bugs1366672
milestone57.0a1
backs outdf6eadeb55a96b0e3d0dd88e65f9b24e06dc2048
e655bcd49af8531bbeca0d931ef1b1220a527886
dd2474c2eaf9386aaa2280e6def86d4d1fc8034a
80a2c096cfa91140438fb9ec39a8d93f40a83d58
64ff8cc86fece89b7b003b1770929f886035fa81
13affa6a958658f4c81bf0eb8fade6012aee1af5
Backed out 6 changesets (bug 1366672) for android linting failures a=backout Backed out changeset df6eadeb55a9 (bug 1366672) Backed out changeset e655bcd49af8 (bug 1366672) Backed out changeset dd2474c2eaf9 (bug 1366672) Backed out changeset 80a2c096cfa9 (bug 1366672) Backed out changeset 64ff8cc86fec (bug 1366672) Backed out changeset 13affa6a9586 (bug 1366672) MozReview-Commit-ID: 9LQiKupMoJb
mobile/android/app/src/main/res/drawable/progressbar.xml
mobile/android/app/src/main/res/drawable/progressbar_normal.xml
mobile/android/app/src/main/res/drawable/progressbar_private.xml
mobile/android/app/src/main/res/layout/customtabs_activity.xml
mobile/android/app/src/main/res/layout/gecko_app.xml
mobile/android/app/src/main/res/values/attrs.xml
mobile/android/app/src/main/res/values/integers.xml
mobile/android/app/src/photon/res/values/colors.xml
mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
mobile/android/base/java/org/mozilla/gecko/drawable/DrawableWrapper.java
mobile/android/base/java/org/mozilla/gecko/drawable/ShiftDrawable.java
mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbar.java
mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarProgressView.java
mobile/android/base/java/org/mozilla/gecko/widget/AnimatedProgressBar.java
mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedProgressBar.java
mobile/android/base/java/org/mozilla/gecko/widget/themed/generate_themed_views.py
mobile/android/base/moz.build
--- a/mobile/android/app/src/main/res/drawable/progressbar.xml
+++ b/mobile/android/app/src/main/res/drawable/progressbar.xml
@@ -1,16 +1,9 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!-- 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/. -->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:gecko="http://schemas.android.com/apk/res-auto">
-
-    <!-- private browsing mode -->
-    <item android:drawable="@drawable/progressbar_private" gecko:state_private="true" />
-
-    <!-- normal modes -->
-    <item android:drawable="@drawable/progressbar_normal" />
-
-</selector>
-
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@android:id/progress">
+        <clip>
+            <shape>
+                <solid android:color="@color/fennec_ui_orange"/>
+            </shape>
+        </clip>
+    </item>
+</layer-list>
deleted file mode 100644
--- a/mobile/android/app/src/main/res/drawable/progressbar_normal.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!-- 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/. -->
-
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:id="@android:id/progress">
-        <scale
-            android:scaleGravity="fill_vertical|start"
-            android:scaleHeight="100%"
-            android:scaleWidth="100%">
-            <shape>
-                <gradient
-                    android:centerColor="@color/photon_loading_indicator_dark"
-                    android:endColor="@color/photon_loading_indicator_light"
-                    android:startColor="@color/photon_loading_indicator_light" />
-            </shape>
-        </scale>
-    </item>
-</layer-list>
deleted file mode 100644
--- a/mobile/android/app/src/main/res/drawable/progressbar_private.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!-- 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/. -->
-
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:id="@android:id/progress">
-        <scale
-            android:scaleGravity="fill_vertical|start"
-            android:scaleHeight="100%"
-            android:scaleWidth="100%">
-            <shape>
-                <gradient
-                    android:centerColor="@color/photon_loading_indicator_dark_private"
-                    android:endColor="@color/photon_loading_indicator_light_private"
-                    android:startColor="@color/photon_loading_indicator_light_private" />
-            </shape>
-        </scale>
-    </item>
-</layer-list>
--- a/mobile/android/app/src/main/res/layout/customtabs_activity.xml
+++ b/mobile/android/app/src/main/res/layout/customtabs_activity.xml
@@ -22,27 +22,25 @@
 
     <org.mozilla.gecko.GeckoView
         android:id="@+id/gecko_view"
         android:layout_width="fill_parent"
         android:layout_below="@id/actionbar"
         android:layout_height="match_parent"
         android:scrollbars="none"/>
 
-    <org.mozilla.gecko.widget.AnimatedProgressBar
+    <ProgressBar
         android:id="@id/page_progress"
         style="@style/Base.Widget.AppCompat.ProgressBar.Horizontal"
         android:layout_width="match_parent"
         android:layout_height="4dp"
         android:layout_alignTop="@id/gecko_view"
         android:background="@drawable/url_bar_bg"
         android:progressDrawable="@drawable/progressbar"
-        app:shiftDuration="@integer/shift_duration_suggestion"
-        app:wrapShiftDrawable="true"
-        tools:progress="70" />
+        tools:progress="70"/>
 
     <View android:id="@+id/custom_tabs_doorhanger_overlay"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:background="@color/dark_transparent_overlay"
         android:alpha="0"
         android:layerType="hardware"/>
 
--- a/mobile/android/app/src/main/res/layout/gecko_app.xml
+++ b/mobile/android/app/src/main/res/layout/gecko_app.xml
@@ -1,19 +1,18 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- 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/. -->
 
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:gecko="http://schemas.android.com/apk/res-auto"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/root_layout"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
+                xmlns:gecko="http://schemas.android.com/apk/res-auto"
+                android:id="@+id/root_layout"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent">
 
     <ViewStub android:id="@+id/tabs_panel"
               android:layout="@layout/tabs_panel_view"
               android:layout_width="match_parent"
               android:layout_height="match_parent"/>
 
    <view class="org.mozilla.gecko.GeckoApp$MainLayout"
          android:id="@+id/main_layout"
@@ -137,28 +136,24 @@
                                                         android:layout_height="match_parent"
                                                         android:layout_width="match_parent"
                                                         style="@style/GeckoActionBar.ActionMode"/>
 
             </ViewFlipper>
 
         </LinearLayout>
 
-        <org.mozilla.gecko.widget.AnimatedProgressBar
-            android:id="@id/page_progress"
-            style="@style/Base.Widget.AppCompat.ProgressBar.Horizontal"
-            android:layout_width="match_parent"
-            android:layout_height="2dp"
-            android:layout_below="@id/browser_chrome"
-            android:layout_marginTop="-2dp"
-            android:background="@null"
-            android:progressDrawable="@drawable/progressbar"
-            android:visibility="gone"
-            app:shiftDuration="@integer/shift_duration_suggestion"
-            app:wrapShiftDrawable="true" />
+        <org.mozilla.gecko.toolbar.ToolbarProgressView android:id="@id/page_progress"
+                                                       android:layout_width="match_parent"
+                                                       android:layout_height="14dp"
+                                                       android:layout_marginTop="-8dp"
+                                                       android:layout_below="@id/browser_chrome"
+                                                       android:src="@drawable/progress"
+                                                       android:background="@null"
+                                                       android:visibility="gone" />
 
     </view>
 
     <FrameLayout android:id="@+id/tab_history_panel"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:layout_alignParentBottom="true"
                  android:visibility="gone" />
--- a/mobile/android/app/src/main/res/values/attrs.xml
+++ b/mobile/android/app/src/main/res/values/attrs.xml
@@ -176,16 +176,10 @@
         <attr name="drawableTintList" format="color" />
     </declare-styleable>
 
     <declare-styleable name="NavButton">
         <attr name="borderColor" format="color" />
         <attr name="borderColorPrivate" format="color" />
     </declare-styleable>
 
-    <declare-styleable name="AnimatedProgressBar">
-        <attr name="wrapShiftDrawable" format="boolean" />
-        <attr name="shiftDuration" format="reference" />
-        <attr name="shiftInterpolator" format="reference" />
-    </declare-styleable>
-
 </resources>
 
--- a/mobile/android/app/src/main/res/values/integers.xml
+++ b/mobile/android/app/src/main/res/values/integers.xml
@@ -8,11 +8,10 @@
     <integer name="number_of_top_sites">6</integer>
     <integer name="number_of_top_sites_cols">2</integer>
     <integer name="max_icon_grid_columns">4</integer>
     <integer name="panel_icon_grid_view_columns">3</integer>
     <integer name="number_of_inline_share_devices">2</integer>
     <integer name="max_search_suggestions">2</integer>
     <integer name="max_saved_suggestions">2</integer>
     <integer name="search_assist_launch_res">0</integer>
-    <integer name="shift_duration_suggestion">300</integer>
 
 </resources>
--- a/mobile/android/app/src/photon/res/values/colors.xml
+++ b/mobile/android/app/src/photon/res/values/colors.xml
@@ -74,16 +74,19 @@
     <color name="photon_two_line_page_row_bg_private">#414146</color>
 
     <color name="photon_search_item_text">@color/photon_text_main</color>
     <color name="photon_search_item_text_private">@color/photon_text_main_private</color>
 
     <color name="photon_home_list_divider">@color/photon_two_line_page_row_bg</color>
     <color name="photon_home_list_divider_private">@color/photon_two_line_page_row_bg_private</color>
 
+    <color name="progress_start">#00DCFC</color>
+    <color name="progress_end">#00A2FE</color>
+
     <color name="photon_url_bar_blocked">#D70022</color>
     <color name="photon_url_bar_blocked_private">#D70022</color>
     <color name="photon_url_bar_certificate_owner">#05A700</color>
     <color name="photon_url_bar_certificate_owner_private">#16DA00</color>
     <color name="photon_url_bar_domain">@color/photon_text_main</color>
     <color name="photon_url_bar_domain_private">@color/photon_text_main_private</color>
 
     <!-- Tab strip color on tablet -->
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -86,16 +86,17 @@ import org.mozilla.gecko.tabs.TabHistory
 import org.mozilla.gecko.tabs.TabHistoryPage;
 import org.mozilla.gecko.tabs.TabsPanel;
 import org.mozilla.gecko.telemetry.TelemetryUploadService;
 import org.mozilla.gecko.telemetry.TelemetryCorePingDelegate;
 import org.mozilla.gecko.telemetry.measurements.SearchCountMeasurements;
 import org.mozilla.gecko.toolbar.AutocompleteHandler;
 import org.mozilla.gecko.toolbar.BrowserToolbar;
 import org.mozilla.gecko.toolbar.BrowserToolbar.TabEditingState;
+import org.mozilla.gecko.toolbar.ToolbarProgressView;
 import org.mozilla.gecko.trackingprotection.TrackingProtectionPrompt;
 import org.mozilla.gecko.updater.PostUpdateHandler;
 import org.mozilla.gecko.updater.UpdateServiceHelper;
 import org.mozilla.gecko.util.ActivityUtils;
 import org.mozilla.gecko.util.Clipboard;
 import org.mozilla.gecko.util.ContextUtils;
 import org.mozilla.gecko.util.DrawableUtil;
 import org.mozilla.gecko.util.EventCallback;
@@ -105,17 +106,16 @@ import org.mozilla.gecko.util.HardwareUt
 import org.mozilla.gecko.util.IntentUtils;
 import org.mozilla.gecko.util.MenuUtils;
 import org.mozilla.gecko.util.PrefUtils;
 import org.mozilla.gecko.util.StringUtils;
 import org.mozilla.gecko.util.ThreadUtils;
 import org.mozilla.gecko.util.WindowUtil;
 import org.mozilla.gecko.widget.ActionModePresenter;
 import org.mozilla.gecko.widget.AnchoredPopup;
-import org.mozilla.gecko.widget.AnimatedProgressBar;
 import org.mozilla.gecko.widget.GeckoActionProvider;
 
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.content.ContentResolver;
@@ -236,17 +236,17 @@ public class BrowserApp extends GeckoApp
     public ViewGroup mBrowserChrome;
     public ViewFlipper mActionBarFlipper;
     public ActionModeCompatView mActionBar;
     private VideoPlayer mVideoPlayer;
     private BrowserToolbar mBrowserToolbar;
     private View doorhangerOverlay;
     // We can't name the TabStrip class because it's not included on API 9.
     private TabStripInterface mTabStrip;
-    private AnimatedProgressBar mProgressView;
+    private ToolbarProgressView mProgressView;
     private FirstrunAnimationContainer mFirstrunAnimationContainer;
     private HomeScreen mHomeScreen;
     private TabsPanel mTabsPanel;
 
     private boolean showSplashScreen = false;
     private SplashScreen splashScreen;
     /**
      * Container for the home screen implementation. This will be populated with any valid
@@ -667,17 +667,17 @@ public class BrowserApp extends GeckoApp
             }
 
             @Override
             public boolean onTouch(View v, MotionEvent event) {
                 return false;
             }
         });
 
-        mProgressView = (AnimatedProgressBar) findViewById(R.id.page_progress);
+        mProgressView = (ToolbarProgressView) findViewById(R.id.page_progress);
         mProgressView.setDynamicToolbar(mDynamicToolbar);
         mBrowserToolbar.setProgressBar(mProgressView);
 
         // Initialize Tab History Controller.
         tabHistoryController = new TabHistoryController(new OnShowTabHistory() {
             @Override
             public void onShowHistory(final List<TabHistoryPage> historyPageList, final int toIndex) {
                 runOnUiThread(new Runnable() {
deleted file mode 100644
--- a/mobile/android/base/java/org/mozilla/gecko/drawable/DrawableWrapper.java
+++ /dev/null
@@ -1,178 +0,0 @@
-package org.mozilla.gecko.drawable;
-/* -*- 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/. */
-
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.ColorFilter;
-import android.graphics.PorterDuff;
-import android.graphics.Rect;
-import android.graphics.Region;
-import android.graphics.drawable.Drawable;
-import android.support.annotation.IntRange;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.util.AttributeSet;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-
-/**
- * DrawableWrapper was added since API Level 23. But in v7 support library, it has annotation
- * "@RestrictTo(LIBRARY_GROUP)". Hence we should not extends it, so we create this wrapper for now.
- * Once we start to support API 23, or v7-support-library allows us to extends its DrawableWrapper,
- * then this file can be removed.
- */
-
-public class DrawableWrapper extends Drawable {
-
-    private final Drawable mWrapped;
-
-    public DrawableWrapper(@NonNull Drawable drawable) {
-        mWrapped = drawable;
-    }
-
-    public Drawable getWrappedDrawable() {
-        return mWrapped;
-    }
-
-    @Override
-    public void draw(@NonNull Canvas canvas) {
-        mWrapped.draw(canvas);
-    }
-
-    @Override
-    public int getChangingConfigurations() {
-        return mWrapped.getChangingConfigurations();
-    }
-
-    @Override
-    public Drawable.ConstantState getConstantState() {
-        return mWrapped.getConstantState();
-    }
-
-    @Override
-    public Drawable getCurrent() {
-        return mWrapped.getCurrent();
-    }
-
-    @Override
-    public int getIntrinsicHeight() {
-        return mWrapped.getIntrinsicHeight();
-    }
-
-    @Override
-    public int getIntrinsicWidth() {
-        return mWrapped.getIntrinsicWidth();
-    }
-
-    @Override
-    public int getMinimumHeight() {
-        return mWrapped.getMinimumHeight();
-    }
-
-    @Override
-    public int getMinimumWidth() {
-        return mWrapped.getMinimumWidth();
-    }
-
-    @Override
-    public int getOpacity() {
-        return mWrapped.getOpacity();
-    }
-
-    @Override
-    public boolean getPadding(Rect padding) {
-        return mWrapped.getPadding(padding);
-    }
-
-    @Override
-    public int[] getState() {
-        return mWrapped.getState();
-    }
-
-    @Override
-    public Region getTransparentRegion() {
-        return mWrapped.getTransparentRegion();
-    }
-
-    @Override
-    public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs)
-            throws XmlPullParserException, IOException {
-        mWrapped.inflate(r, parser, attrs);
-    }
-
-    @Override
-    public boolean isStateful() {
-        return mWrapped.isStateful();
-    }
-
-    @Override
-    public void jumpToCurrentState() {
-        mWrapped.jumpToCurrentState();
-    }
-
-    @Override
-    public Drawable mutate() {
-        return mWrapped.mutate();
-    }
-
-    @Override
-    public void setAlpha(@IntRange(from = 0, to = 255) int i) {
-        mWrapped.setAlpha(i);
-    }
-
-    @Override
-    public void scheduleSelf(Runnable what, long when) {
-        mWrapped.scheduleSelf(what, when);
-    }
-
-    @Override
-    public void setChangingConfigurations(int configs) {
-        mWrapped.setChangingConfigurations(configs);
-    }
-
-    @Override
-    public void setColorFilter(@Nullable ColorFilter colorFilter) {
-        mWrapped.setColorFilter(colorFilter);
-    }
-
-    @Override
-    public void setColorFilter(int color, PorterDuff.Mode mode) {
-        mWrapped.setColorFilter(color, mode);
-    }
-
-    @Override
-    public void setFilterBitmap(boolean filter) {
-        mWrapped.setFilterBitmap(filter);
-    }
-
-    @Override
-    public boolean setVisible(boolean visible, boolean restart) {
-        return mWrapped.setVisible(visible, restart);
-    }
-
-    @Override
-    public void unscheduleSelf(Runnable what) {
-        mWrapped.unscheduleSelf(what);
-    }
-
-    @Override
-    protected void onBoundsChange(Rect bounds) {
-        mWrapped.setBounds(bounds);
-    }
-
-    @Override
-    protected boolean onLevelChange(int level) {
-        return mWrapped.setLevel(level);
-    }
-
-    @Override
-    protected boolean onStateChange(int[] state) {
-        return mWrapped.setState(state);
-    }
-}
deleted file mode 100644
--- a/mobile/android/base/java/org/mozilla/gecko/drawable/ShiftDrawable.java
+++ /dev/null
@@ -1,156 +0,0 @@
-package org.mozilla.gecko.drawable;
-
-/* -*- 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/. */
-
-import android.animation.Animator;
-import android.animation.ValueAnimator;
-import android.graphics.Canvas;
-import android.graphics.Path;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.view.animation.Interpolator;
-import android.view.animation.LinearInterpolator;
-
-/**
- * A drawable to keep shifting its wrapped drawable.
- * Assume the wrapped drawable value is "00000010", this class will keep drawing in this way
- * <p>
- * 00000010 -> 00000001 -> 10000000 -> 01000000 -> 00100000 -> ...
- * <p>
- * This drawable will keep drawing until be invisible.
- */
-public class ShiftDrawable extends DrawableWrapper {
-
-    /**
-     * An animator to trigger redraw and update offset-of-shifting
-     */
-    private final ValueAnimator mAnimator = ValueAnimator.ofFloat(0f, 1f);
-
-    /**
-     * Visible rectangle, wrapped-drawable is resized and draw in this rectangle
-     */
-    private final Rect mVisibleRect = new Rect();
-
-    /**
-     * Canvas will clip itself by this Path. Used to draw rounded head.
-     */
-    private final Path mPath = new Path();
-
-    // align to ScaleDrawable implementation
-    private static final int MAX_LEVEL = 10000;
-
-    private static final int DEFAULT_DURATION = 1000;
-
-    public ShiftDrawable(@NonNull Drawable d) {
-        this(d, DEFAULT_DURATION);
-    }
-
-    public ShiftDrawable(@NonNull Drawable d, int duration) {
-        this(d, duration, new LinearInterpolator());
-    }
-
-    public ShiftDrawable(@NonNull Drawable d, int duration, @Nullable Interpolator interpolator) {
-        super(d);
-        mAnimator.setDuration(duration);
-        mAnimator.setRepeatCount(ValueAnimator.INFINITE);
-        mAnimator.setInterpolator((interpolator == null) ? new LinearInterpolator() : interpolator);
-        mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                if (isVisible()) {
-                    invalidateSelf();
-                }
-            }
-        });
-        mAnimator.start();
-    }
-
-    public Animator getAnimator() {
-        return mAnimator;
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p>
-     * override to enable / disable animator as well.
-     */
-    @Override
-    public boolean setVisible(final boolean visible, final boolean restart) {
-        final boolean result = super.setVisible(visible, restart);
-        if (isVisible()) {
-            mAnimator.start();
-        } else {
-            mAnimator.end();
-        }
-        return result;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected void onBoundsChange(Rect bounds) {
-        super.onBoundsChange(bounds);
-        updateBounds();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected boolean onLevelChange(int level) {
-        final boolean result = super.onLevelChange(level);
-        updateBounds();
-        return result;
-    }
-
-    @Override
-    public void draw(@NonNull Canvas canvas) {
-        final Drawable wrapped = getWrappedDrawable();
-        final float fraction = mAnimator.getAnimatedFraction();
-        final int width = mVisibleRect.width();
-        final int offset = (int) (width * fraction);
-
-        final int stack = canvas.save();
-
-        // To apply mPath, then we have rounded-head
-        canvas.clipPath(mPath);
-
-        // To draw left-half part of Drawable, shift from right to left
-        canvas.save();
-        canvas.translate(-offset, 0);
-        wrapped.draw(canvas);
-        canvas.restore();
-
-        // Then to draw right-half part of Drawable
-        canvas.save();
-        canvas.translate(width - offset, 0);
-        wrapped.draw(canvas);
-        canvas.restore();
-
-        canvas.restoreToCount(stack);
-    }
-
-    private void updateBounds() {
-        final Rect b = getBounds();
-        final int width = (int) ((float) b.width() * getLevel() / MAX_LEVEL);
-        mVisibleRect.set(b.left, b.top, b.left + width, b.height());
-
-        // to create path to help drawing rounded head. mPath is enclosed by mVisibleRect
-        final float radius = b.height() / 2;
-        mPath.reset();
-
-        // The added rectangle width is smaller than mVisibleRect, due to semi-circular.
-        mPath.addRect(mVisibleRect.left,
-                mVisibleRect.top, mVisibleRect.right - radius,
-                mVisibleRect.height(),
-                Path.Direction.CCW);
-        // To add semi-circular
-        mPath.addCircle(mVisibleRect.right - radius, radius, radius, Path.Direction.CCW);
-    }
-}
--- a/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbar.java
+++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbar.java
@@ -29,18 +29,18 @@ import org.mozilla.gecko.menu.MenuPopup;
 import org.mozilla.gecko.preferences.GeckoPreferences;
 import org.mozilla.gecko.tabs.TabHistoryController;
 import org.mozilla.gecko.toolbar.ToolbarDisplayLayout.OnStopListener;
 import org.mozilla.gecko.toolbar.ToolbarDisplayLayout.OnTitleChangeListener;
 import org.mozilla.gecko.toolbar.ToolbarDisplayLayout.UpdateFlags;
 import org.mozilla.gecko.util.Clipboard;
 import org.mozilla.gecko.util.MenuUtils;
 import org.mozilla.gecko.util.WindowUtil;
-import org.mozilla.gecko.widget.AnimatedProgressBar;
 import org.mozilla.gecko.widget.themed.ThemedImageButton;
+import org.mozilla.gecko.widget.themed.ThemedImageView;
 import org.mozilla.gecko.widget.themed.ThemedRelativeLayout;
 
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.StateListDrawable;
@@ -113,17 +113,17 @@ public abstract class BrowserToolbar ext
     }
 
     protected final ToolbarDisplayLayout urlDisplayLayout;
     protected final ToolbarEditLayout urlEditLayout;
     protected final View urlBarEntry;
     protected boolean isSwitchingTabs;
     protected final ThemedImageButton tabsButton;
 
-    private AnimatedProgressBar progressBar;
+    private ToolbarProgressView progressBar;
     protected final TabCounter tabsCounter;
     protected final View menuButton;
     private MenuPopup menuPopup;
     protected final List<View> focusOrder;
 
     private OnActivateListener activateListener;
     private OnFocusChangeListener focusChangeListener;
     private OnStartEditingListener startEditingListener;
@@ -349,25 +349,26 @@ public abstract class BrowserToolbar ext
         final int height = getHeight();
         canvas.drawRect(0, height - shadowSize, getWidth(), height, shadowPaint);
     }
 
     public void onParentFocus() {
         urlEditLayout.onParentFocus();
     }
 
-    public void setProgressBar(AnimatedProgressBar progressBar) {
+    public void setProgressBar(ToolbarProgressView progressBar) {
         this.progressBar = progressBar;
     }
 
     public void setTabHistoryController(TabHistoryController tabHistoryController) {
         this.tabHistoryController = tabHistoryController;
     }
 
     public void refresh() {
+        progressBar.setImageDrawable(getResources().getDrawable(R.drawable.progress));
         urlDisplayLayout.dismissSiteIdentityPopup();
         urlEditLayout.refresh();
     }
 
     public boolean onBackPressed() {
         // If we exit editing mode during the animation,
         // we're put into an inconsistent state (bug 1017276).
         if (isEditing() && !isAnimating()) {
@@ -434,27 +435,26 @@ public abstract class BrowserToolbar ext
 
         if (tabs.isSelectedTab(tab)) {
             final EnumSet<UpdateFlags> flags = EnumSet.noneOf(UpdateFlags.class);
 
             // Progress-related handling
             switch (msg) {
                 case START:
                     updateProgressVisibility(tab, Tab.LOAD_PROGRESS_INIT);
-                    break;
+                    // Fall through.
                 case ADDED:
                 case LOCATION_CHANGE:
                 case LOAD_ERROR:
                 case LOADED:
                 case STOP:
                     flags.add(UpdateFlags.PROGRESS);
                     if (progressBar.getVisibility() == View.VISIBLE) {
-                        progressBar.setProgress(tab.getLoadProgress());
+                        progressBar.animateProgress(tab.getLoadProgress());
                     }
-                    updateProgressVisibility();
                     break;
 
                 case SELECTED:
                     flags.add(UpdateFlags.PROGRESS);
                     updateProgressVisibility();
                     break;
             }
 
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarProgressView.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2010 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 org.mozilla.gecko.toolbar;
+
+import android.support.v4.content.ContextCompat;
+
+import org.mozilla.gecko.R;
+import org.mozilla.gecko.widget.themed.ThemedImageView;
+import org.mozilla.gecko.util.WeakReferenceHandler;
+import org.mozilla.gecko.DynamicToolbar;
+import org.mozilla.gecko.DynamicToolbar.VisibilityTransition;
+import org.mozilla.gecko.gfx.DynamicToolbarAnimator.PinReason;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Message;
+import android.support.v4.view.ViewCompat;
+import android.util.AttributeSet;
+import android.view.View;
+
+/**
+ * Progress view used for page loads.
+ *
+ * Because we're given limited information about the page load progress, the
+ * bar also includes incremental animation between each step to improve
+ * perceived performance.
+ */
+public class ToolbarProgressView extends ThemedImageView {
+    private static final int MAX_PROGRESS = 10000;
+    private static final int MSG_UPDATE = 0;
+    private static final int MSG_HIDE = 1;
+    private static final int STEPS = 10;
+    private static final int DELAY = 40;
+
+    private int mTargetProgress;
+    private int mIncrement;
+    private ProgressBounds mBounds;
+    private Handler mHandler;
+    private int mCurrentProgress;
+    private DynamicToolbar mDynamicToolbar;
+
+    private PorterDuffColorFilter mPrivateBrowsingColorFilter;
+
+    public ToolbarProgressView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        init(context);
+    }
+
+    public ToolbarProgressView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init(context);
+    }
+
+    public void setDynamicToolbar(DynamicToolbar toolbar) {
+        mDynamicToolbar = toolbar;
+    }
+
+    private void init(Context ctx) {
+        mBounds = new ProgressBounds();
+
+        mTargetProgress = 0;
+
+        mPrivateBrowsingColorFilter = new PorterDuffColorFilter(
+                ContextCompat.getColor(ctx, R.color.private_browsing_purple), PorterDuff.Mode.SRC_IN);
+
+        mHandler = new ToolbarProgressHandler(this);
+    }
+
+    void pinDynamicToolbar() {
+        if ((mDynamicToolbar != null) && mDynamicToolbar.isEnabled()) {
+            mDynamicToolbar.setPinned(true, PinReason.PAGE_LOADING);
+            mDynamicToolbar.setVisible(true, VisibilityTransition.ANIMATE);
+        }
+    }
+
+    void unpinDynamicToolbar() {
+        if ((mDynamicToolbar != null) && mDynamicToolbar.isEnabled()) {
+            mDynamicToolbar.setPinned(false, PinReason.PAGE_LOADING);
+        }
+    }
+
+    @Override
+    public void onLayout(boolean f, int l, int t, int r, int b) {
+        mBounds.setLayoutRtl(ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL);
+        mBounds.onLayout(f, l, t, r, b);
+    }
+
+    @Override
+    public void onDraw(Canvas canvas) {
+        final Drawable d = getDrawable();
+        d.setBounds(mBounds.getBounds());
+        d.draw(canvas);
+    }
+
+    /**
+     * Immediately sets the progress bar to the given progress percentage.
+     *
+     * @param progressPercentage Percentage (0-100) to which progress bar should be set
+     */
+    void setProgress(int progressPercentage) {
+        mCurrentProgress = mTargetProgress = getAbsoluteProgress(progressPercentage);
+        updateBounds();
+
+        clearMessages();
+    }
+
+    /**
+     * Animates the progress bar from the current progress value to the given
+     * progress percentage.
+     *
+     * @param progressPercentage Percentage (0-100) to which progress bar should be animated
+     */
+    void animateProgress(int progressPercentage) {
+        final int absoluteProgress = getAbsoluteProgress(progressPercentage);
+        if (absoluteProgress <= mTargetProgress) {
+            // After we manually click stop, we can still receive page load
+            // events (e.g., DOMContentLoaded). Updating for other updates
+            // after a STOP event can freeze the progress bar, so guard against
+            // that here.
+            return;
+        }
+
+        mTargetProgress = absoluteProgress;
+        mIncrement = (mTargetProgress - mCurrentProgress) / STEPS;
+
+        clearMessages();
+        mHandler.sendEmptyMessage(MSG_UPDATE);
+    }
+
+    private void clearMessages() {
+        mHandler.removeMessages(MSG_UPDATE);
+        mHandler.removeMessages(MSG_HIDE);
+    }
+
+    private int getAbsoluteProgress(int progressPercentage) {
+        if (progressPercentage < 0) {
+            return 0;
+        }
+
+        if (progressPercentage > 100) {
+            return 100;
+        }
+
+        return progressPercentage * MAX_PROGRESS / 100;
+    }
+
+    private void updateBounds() {
+        mBounds.updateBounds();
+        invalidate();
+    }
+
+    @Override
+    public void setPrivateMode(final boolean isPrivate) {
+        super.setPrivateMode(isPrivate);
+
+        // Note: android:tint is better but ColorStateLists are not supported until API 21.
+        if (isPrivate) {
+            setColorFilter(mPrivateBrowsingColorFilter);
+        } else {
+            clearColorFilter();
+        }
+    }
+
+    private static class ToolbarProgressHandler extends WeakReferenceHandler<ToolbarProgressView> {
+        public ToolbarProgressHandler(final ToolbarProgressView that) {
+            super(that);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            final ToolbarProgressView that = mTarget.get();
+            if (that == null) {
+                return;
+            }
+
+            switch (msg.what) {
+                case MSG_UPDATE:
+                    that.mCurrentProgress = Math.min(that.mTargetProgress, that.mCurrentProgress + that.mIncrement);
+
+                    that.updateBounds();
+
+                    if (that.mCurrentProgress < that.mTargetProgress) {
+                        final int delay = (that.mTargetProgress < MAX_PROGRESS) ? DELAY : DELAY / 4;
+                        sendMessageDelayed(that.mHandler.obtainMessage(msg.what), delay);
+                    } else if (that.mCurrentProgress == MAX_PROGRESS) {
+                        sendMessageDelayed(that.mHandler.obtainMessage(MSG_HIDE), DELAY);
+                    }
+                    break;
+
+                case MSG_HIDE:
+                    that.setVisibility(View.GONE);
+                    that.unpinDynamicToolbar();
+                    break;
+            }
+        }
+    };
+
+    private final class ProgressBounds {
+
+        final Rect bounds;
+        boolean isLayoutRtl = false;
+
+        ProgressBounds() {
+            bounds = new Rect();
+        }
+
+        public Rect getBounds() {
+            return bounds;
+        }
+
+        void setLayoutRtl(boolean isLayoutRtl) {
+            this.isLayoutRtl = isLayoutRtl;
+        }
+
+        void updateBounds() {
+            int progressWidth = getWidth() * mCurrentProgress / MAX_PROGRESS;
+            if (isLayoutRtl) {
+                bounds.left = getWidth() - progressWidth;
+            } else {
+                bounds.right = progressWidth;
+            }
+        }
+
+        void onLayout(boolean f, int l, int t, int r, int b) {
+            bounds.top = 0;
+            bounds.bottom = b - t;
+            int progressWidth = (r - l) * mCurrentProgress / MAX_PROGRESS;
+            ;
+            if (isLayoutRtl) {
+                bounds.left = r - progressWidth;
+                bounds.right = r;
+            } else {
+                bounds.left = 0;
+                bounds.right = progressWidth;
+            }
+        }
+    }
+}
deleted file mode 100644
--- a/mobile/android/base/java/org/mozilla/gecko/widget/AnimatedProgressBar.java
+++ /dev/null
@@ -1,334 +0,0 @@
-/* -*- 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.Animator;
-import android.animation.ValueAnimator;
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
-import android.os.Handler;
-import android.support.annotation.InterpolatorRes;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v4.view.ViewCompat;
-import android.util.AttributeSet;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-import android.view.animation.LinearInterpolator;
-
-import org.mozilla.gecko.DynamicToolbar;
-import org.mozilla.gecko.R;
-import org.mozilla.gecko.drawable.ShiftDrawable;
-import org.mozilla.gecko.gfx.DynamicToolbarAnimator;
-import org.mozilla.gecko.widget.themed.ThemedProgressBar;
-
-/**
- * A progressbar with some animations on changing progress.
- * When changing progress of this bar, it does not change value directly. Instead, it use
- * {@link Animator} to change value progressively. Moreover, change visibility to View.GONE will
- * cause closing animation.
- */
-public class AnimatedProgressBar extends ThemedProgressBar {
-
-    /**
-     * Animation duration of progress changing.
-     */
-    private final static int PROGRESS_DURATION = 200;
-
-    /**
-     * Delay before applying closing animation when progress reach max value.
-     */
-    private final static int CLOSING_DELAY = 300;
-
-    /**
-     * Animation duration for closing
-     */
-    private final static int CLOSING_DURATION = 300;
-
-    private ValueAnimator mPrimaryAnimator;
-    private final ValueAnimator mClosingAnimator = ValueAnimator.ofFloat(0f, 1f);
-
-    /**
-     * For closing animation. To indicate how many visible region should be clipped.
-     */
-    private float mClipRatio = 0f;
-    private final Rect mRect = new Rect();
-
-    /**
-     * To store the final expected progress to reach, it does matter in animation.
-     */
-    private int mExpectedProgress = 0;
-
-    /**
-     * setProgress() might be invoked in constructor. Add to flag to avoid null checking for animators.
-     */
-    private boolean mInitialized = false;
-
-    private boolean mIsRtl = false;
-
-    private DynamicToolbar mDynamicToolbar;
-    private EndingRunner mEndingRunner = new EndingRunner();
-
-    private final ValueAnimator.AnimatorUpdateListener mListener =
-            new ValueAnimator.AnimatorUpdateListener() {
-                @Override
-                public void onAnimationUpdate(ValueAnimator animation) {
-                    setProgressImmediately((int) mPrimaryAnimator.getAnimatedValue());
-                }
-            };
-
-    public AnimatedProgressBar(@NonNull Context context) {
-        super(context, null);
-        init(context, null);
-    }
-
-    public AnimatedProgressBar(@NonNull Context context,
-                               @Nullable AttributeSet attrs) {
-        super(context, attrs);
-        init(context, attrs);
-    }
-
-    public AnimatedProgressBar(@NonNull Context context,
-                               @Nullable AttributeSet attrs,
-                               int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        init(context, attrs);
-    }
-
-    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
-    public AnimatedProgressBar(Context context,
-                               AttributeSet attrs,
-                               int defStyleAttr,
-                               int defStyleRes) {
-        super(context, attrs, defStyleAttr);
-        init(context, attrs);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public synchronized void setMax(int max) {
-        super.setMax(max);
-        mPrimaryAnimator = createAnimator(getMax(), mListener);
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p>
-     * Instead of set progress directly, this method triggers an animator to change progress.
-     */
-    @Override
-    public void setProgress(int nextProgress) {
-        nextProgress = Math.min(nextProgress, getMax());
-        nextProgress = Math.max(0, nextProgress);
-        mExpectedProgress = nextProgress;
-        if (!mInitialized) {
-            setProgressImmediately(mExpectedProgress);
-            return;
-        }
-
-        if (mExpectedProgress < getProgress()) {
-            setProgressImmediately(0);
-        }
-
-        // Animation is not needed for reloading a completed page
-        if ((mExpectedProgress == 0) && (getProgress() == getMax())) {
-            mPrimaryAnimator.cancel();
-            mClosingAnimator.cancel();
-            mClipRatio = 0f;
-
-            setProgressImmediately(0);
-            return;
-        }
-
-        mPrimaryAnimator.cancel();
-        mPrimaryAnimator.setIntValues(getProgress(), nextProgress);
-        mPrimaryAnimator.start();
-
-        if (nextProgress != getMax()) {
-            // stop closing animation
-            mClosingAnimator.cancel();
-            mClipRatio = 0f;
-        }
-    }
-
-    @Override
-    public void onDraw(Canvas canvas) {
-        if (mClipRatio == 0) {
-            super.onDraw(canvas);
-        } else {
-            canvas.getClipBounds(mRect);
-            final float clipWidth = mRect.width() * mClipRatio;
-            canvas.save();
-            if (mIsRtl) {
-                canvas.clipRect(mRect.left, mRect.top, mRect.right - clipWidth, mRect.bottom);
-            } else {
-                canvas.clipRect(mRect.left + clipWidth, mRect.top, mRect.right, mRect.bottom);
-            }
-            super.onDraw(canvas);
-            canvas.restore();
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p>
-     * Instead of change visibility directly, this method also applies the closing animation if
-     * progress reaches max value.
-     */
-    @Override
-    public void setVisibility(int value) {
-        // nothing changed
-        if (getVisibility() == value) {
-            return;
-        }
-
-        if (value == GONE) {
-            if (mExpectedProgress == getMax()) {
-                setProgressImmediately(mExpectedProgress);
-                animateClosing();
-            } else {
-                setVisibilityImmediately(value);
-            }
-        } else {
-            final Handler handler = getHandler();
-            // if this view is detached from window, the handler would be null
-            if (handler != null) {
-                getHandler().removeCallbacks(mEndingRunner);
-            }
-
-            if (mClosingAnimator != null) {
-                mClosingAnimator.cancel();
-            }
-            setVisibilityImmediately(value);
-        }
-    }
-
-    @Override
-    public void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        mIsRtl = (ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL);
-    }
-
-    public void setDynamicToolbar(@Nullable DynamicToolbar toolbar) {
-        mDynamicToolbar = toolbar;
-    }
-
-    public void pinDynamicToolbar() {
-        if (mDynamicToolbar == null) {
-            return;
-        }
-        if (mDynamicToolbar.isEnabled()) {
-            mDynamicToolbar.setPinned(true, DynamicToolbarAnimator.PinReason.PAGE_LOADING);
-            mDynamicToolbar.setVisible(true, DynamicToolbar.VisibilityTransition.ANIMATE);
-        }
-    }
-
-    public void unpinDynamicToolbar() {
-        if (mDynamicToolbar == null) {
-            return;
-        }
-        if (mDynamicToolbar.isEnabled()) {
-            mDynamicToolbar.setPinned(false, DynamicToolbarAnimator.PinReason.PAGE_LOADING);
-        }
-    }
-
-    private void init(@NonNull Context context, @Nullable AttributeSet attrs) {
-        mInitialized = true;
-
-        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AnimatedProgressBar);
-        final int duration = a.getInteger(R.styleable.AnimatedProgressBar_shiftDuration, 1000);
-        final boolean wrap = a.getBoolean(R.styleable.AnimatedProgressBar_wrapShiftDrawable, false);
-        @InterpolatorRes final int itplId = a.getResourceId(R.styleable.AnimatedProgressBar_shiftInterpolator, 0);
-        a.recycle();
-
-        setProgressDrawable(buildDrawable(getProgressDrawable(), wrap, duration, itplId));
-
-        mPrimaryAnimator = createAnimator(getMax(), mListener);
-
-        mClosingAnimator.setDuration(CLOSING_DURATION);
-        mClosingAnimator.setInterpolator(new LinearInterpolator());
-        mClosingAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator valueAnimator) {
-                mClipRatio = (float) valueAnimator.getAnimatedValue();
-                invalidate();
-            }
-        });
-        mClosingAnimator.addListener(new Animator.AnimatorListener() {
-            @Override
-            public void onAnimationStart(Animator animator) {
-                mClipRatio = 0f;
-            }
-
-            @Override
-            public void onAnimationEnd(Animator animator) {
-                setVisibilityImmediately(GONE);
-            }
-
-            @Override
-            public void onAnimationCancel(Animator animator) {
-                mClipRatio = 0f;
-            }
-
-            @Override
-            public void onAnimationRepeat(Animator animator) {
-            }
-        });
-    }
-
-    private void setVisibilityImmediately(int value) {
-        super.setVisibility(value);
-    }
-
-    private void animateClosing() {
-        mClosingAnimator.cancel();
-        final Handler handler = getHandler();
-        // if this view is detached from window, the handler would be null
-        if (handler != null) {
-            handler.postDelayed(mEndingRunner, CLOSING_DELAY);
-        }
-    }
-
-    private void setProgressImmediately(int progress) {
-        super.setProgress(progress);
-    }
-
-    private Drawable buildDrawable(@NonNull Drawable original,
-                                   boolean isWrap,
-                                   int duration,
-                                   @InterpolatorRes int itplId) {
-        if (isWrap) {
-            final Interpolator interpolator = (itplId > 0)
-                    ? AnimationUtils.loadInterpolator(getContext(), itplId)
-                    : null;
-            return new ShiftDrawable(original, duration, interpolator);
-        } else {
-            return original;
-        }
-    }
-
-    private static ValueAnimator createAnimator(int max, ValueAnimator.AnimatorUpdateListener listener) {
-        ValueAnimator animator = ValueAnimator.ofInt(0, max);
-        animator.setInterpolator(new LinearInterpolator());
-        animator.setDuration(PROGRESS_DURATION);
-        animator.addUpdateListener(listener);
-        return animator;
-    }
-
-    private class EndingRunner implements Runnable {
-        @Override
-        public void run() {
-            mClosingAnimator.start();
-        }
-    }
-}
deleted file mode 100644
--- a/mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedProgressBar.java
+++ /dev/null
@@ -1,172 +0,0 @@
-// This file is generated by generate_themed_views.py; do not edit.
-
-/* 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.themed;
-
-import android.support.v4.content.ContextCompat;
-import org.mozilla.gecko.GeckoApplication;
-import org.mozilla.gecko.lwt.LightweightTheme;
-import org.mozilla.gecko.R;
-import org.mozilla.gecko.util.DrawableUtil;
-
-import android.content.Context;
-import android.content.res.ColorStateList;
-import android.content.res.TypedArray;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-
-public class ThemedProgressBar extends android.widget.ProgressBar
-                                     implements LightweightTheme.OnChangeListener {
-    private LightweightTheme theme;
-
-    private static final int[] STATE_PRIVATE_MODE = { R.attr.state_private };
-    private static final int[] STATE_LIGHT = { R.attr.state_light };
-    private static final int[] STATE_DARK = { R.attr.state_dark };
-
-    protected static final int[] PRIVATE_PRESSED_STATE_SET = { R.attr.state_private, android.R.attr.state_pressed };
-    protected static final int[] PRIVATE_FOCUSED_STATE_SET = { R.attr.state_private, android.R.attr.state_focused };
-    protected static final int[] PRIVATE_STATE_SET = { R.attr.state_private };
-
-    private boolean isPrivate;
-    private boolean isLight;
-    private boolean isDark;
-    private boolean autoUpdateTheme;        // always false if there's no theme.
-
-    private ColorStateList drawableColors;
-
-    public ThemedProgressBar(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        initialize(context, attrs, 0);
-    }
-
-    public ThemedProgressBar(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        initialize(context, attrs, defStyle);
-    }
-
-    private void initialize(final Context context, final AttributeSet attrs, final int defStyle) {
-        // The theme can be null, particularly if we might be instantiating this
-        // View in an IDE, with no ambient GeckoApplication.
-        final Context applicationContext = context.getApplicationContext();
-        if (applicationContext instanceof GeckoApplication) {
-            theme = ((GeckoApplication) applicationContext).getLightweightTheme();
-        }
-
-        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LightweightTheme);
-        autoUpdateTheme = theme != null && a.getBoolean(R.styleable.LightweightTheme_autoUpdateTheme, true);
-        a.recycle();
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-
-        if (autoUpdateTheme)
-            theme.addListener(this);
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-
-        if (autoUpdateTheme)
-            theme.removeListener(this);
-    }
-
-    @Override
-    public int[] onCreateDrawableState(int extraSpace) {
-        final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
-
-        if (isPrivate)
-            mergeDrawableStates(drawableState, STATE_PRIVATE_MODE);
-        else if (isLight)
-            mergeDrawableStates(drawableState, STATE_LIGHT);
-        else if (isDark)
-            mergeDrawableStates(drawableState, STATE_DARK);
-
-        return drawableState;
-    }
-
-    @Override
-    public void onLightweightThemeChanged() {
-        if (autoUpdateTheme && theme.isEnabled())
-            setTheme(theme.isLightTheme());
-    }
-
-    @Override
-    public void onLightweightThemeReset() {
-        if (autoUpdateTheme)
-            resetTheme();
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
-        onLightweightThemeChanged();
-    }
-
-    public boolean isPrivateMode() {
-        return isPrivate;
-    }
-
-    public void setPrivateMode(boolean isPrivate) {
-        if (this.isPrivate != isPrivate) {
-            this.isPrivate = isPrivate;
-            refreshDrawableState();
-            invalidate();
-        }
-    }
-
-    public void setTheme(boolean isLight) {
-        // Set the theme only if it is different from existing theme.
-        if ((isLight && this.isLight != isLight) ||
-            (!isLight && this.isDark == isLight)) {
-            if (isLight) {
-                this.isLight = true;
-                this.isDark = false;
-            } else {
-                this.isLight = false;
-                this.isDark = true;
-            }
-
-            refreshDrawableState();
-            invalidate();
-        }
-    }
-
-    public void resetTheme() {
-        if (isLight || isDark) {
-            isLight = false;
-            isDark = false;
-            refreshDrawableState();
-            invalidate();
-        }
-    }
-
-    public void setAutoUpdateTheme(boolean autoUpdateTheme) {
-        if (theme == null) {
-            return;
-        }
-
-        if (this.autoUpdateTheme != autoUpdateTheme) {
-            this.autoUpdateTheme = autoUpdateTheme;
-
-            if (autoUpdateTheme)
-                theme.addListener(this);
-            else
-                theme.removeListener(this);
-        }
-    }
-
-    public ColorDrawable getColorDrawable(int id) {
-        return new ColorDrawable(ContextCompat.getColor(getContext(), id));
-    }
-
-    protected LightweightTheme getTheme() {
-        return theme;
-    }
-}
--- a/mobile/android/base/java/org/mozilla/gecko/widget/themed/generate_themed_views.py
+++ b/mobile/android/base/java/org/mozilla/gecko/widget/themed/generate_themed_views.py
@@ -58,19 +58,16 @@ views = [
          BASE_TYPE='android.widget.TextView',
          STYLE_CONSTRUCTOR=1),
     dict(VIEW_NAME_SUFFIX='View',
          BASE_TYPE='android.view.View',
          STYLE_CONSTRUCTOR=1),
     dict(VIEW_NAME_SUFFIX='ListView',
          BASE_TYPE='android.widget.ListView',
          STYLE_CONSTRUCTOR=1),
-    dict(VIEW_NAME_SUFFIX='ProgressBar',
-         BASE_TYPE='android.widget.ProgressBar',
-         STYLE_CONSTRUCTOR=1),
 ]
 
 for view in views:
     pp = Preprocessor(defines=view, marker='//#')
 
     dest = os.path.join(__DIR__, dest_format_string % view)
     with open(template, 'rU') as input:
         with open(dest, 'wt') as output:
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -613,18 +613,16 @@ gbjar.sources += ['java/org/mozilla/geck
     'dlc/DownloadAction.java',
     'dlc/DownloadContentService.java',
     'dlc/DownloadContentTelemetry.java',
     'dlc/StudyAction.java',
     'dlc/SyncAction.java',
     'dlc/VerifyAction.java',
     'DoorHangerPopup.java',
     'DownloadsIntegration.java',
-    'drawable/DrawableWrapper.java',
-    'drawable/ShiftDrawable.java',
     'DynamicToolbar.java',
     'EditBookmarkDialog.java',
     'Experiments.java',
     'feeds/action/CheckForUpdatesAction.java',
     'feeds/action/EnrollSubscriptionsAction.java',
     'feeds/action/FeedAction.java',
     'feeds/action/SetupAlarmsAction.java',
     'feeds/action/SubscribeToFeedAction.java',
@@ -938,16 +936,17 @@ gbjar.sources += ['java/org/mozilla/geck
     'toolbar/PhoneTabsButton.java',
     'toolbar/SecurityModeUtil.java',
     'toolbar/ShapedButton.java',
     'toolbar/ShapedButtonFrameLayout.java',
     'toolbar/SiteIdentityPopup.java',
     'toolbar/ToolbarEditLayout.java',
     'toolbar/ToolbarEditText.java',
     'toolbar/ToolbarPrefs.java',
+    'toolbar/ToolbarProgressView.java',
     'trackingprotection/TrackingProtectionPrompt.java',
     'updater/PostUpdateHandler.java',
     'updater/UpdateService.java',
     'updater/UpdateServiceHelper.java',
     'util/ColorUtil.java',
     'util/DrawableUtil.java',
     'util/JavaUtil.java',
     'util/ResourceDrawableUtils.java',
@@ -958,17 +957,16 @@ gbjar.sources += ['java/org/mozilla/geck
     'webapps/WebAppActivity.java',
     'webapps/WebAppIndexer.java',
     'webapps/WebApps.java',
     'widget/ActionModePresenter.java',
     'widget/ActivityChooserModel.java',
     'widget/AllCapsTextView.java',
     'widget/AnchoredPopup.java',
     'widget/AnimatedHeightLayout.java',
-    'widget/AnimatedProgressBar.java',
     'widget/BasicColorPicker.java',
     'widget/CheckableLinearLayout.java',
     'widget/ClickableWhenDisabledEditText.java',
     'widget/ContentSecurityDoorHanger.java',
     'widget/CropImageView.java',
     'widget/DateTimePicker.java',
     'widget/DefaultDoorHanger.java',
     'widget/DefaultItemAnimatorBase.java',
@@ -1005,17 +1003,16 @@ gbjar.sources += ['java/org/mozilla/geck
 # If you're editing this list, make sure to edit that script.
 gbjar.sources += ['java/org/mozilla/gecko/' + x for x in [
     'widget/themed/ThemedEditText.java',
     'widget/themed/ThemedFrameLayout.java',
     'widget/themed/ThemedImageButton.java',
     'widget/themed/ThemedImageView.java',
     'widget/themed/ThemedLinearLayout.java',
     'widget/themed/ThemedListView.java',
-    'widget/themed/ThemedProgressBar.java',
     'widget/themed/ThemedRelativeLayout.java',
     'widget/themed/ThemedTextSwitcher.java',
     'widget/themed/ThemedTextView.java',
     'widget/themed/ThemedView.java',
 ]]
 # The following sources are Photon specific, Eventually they should be merged into base.
 gbjar.sources += ['../app/src/photon/java/org/mozilla/gecko/' + x for x in [
     'home/SearchEngineRow.java',