Bug 970719 - Animate progress bar to end of the screen. r=lucasr, a=sledru
authorBrian Nicholson <bnicholson@mozilla.com>
Wed, 12 Feb 2014 21:47:11 -0800
changeset 177075 fe87bde35f743b45b69b6c6776b7abca31885fa6
parent 177074 1b5e18e67fdf39ff2f7a729aa40f136c6b01705f
child 177076 c67b7129565ab1aa0bc0146b959037ba0b07af90
push id5244
push userryanvm@gmail.com
push dateMon, 17 Feb 2014 01:41:29 +0000
treeherdermozilla-aurora@c67b7129565a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslucasr, sledru
bugs970719
milestone29.0a2
Bug 970719 - Animate progress bar to end of the screen. r=lucasr, a=sledru
mobile/android/base/Tabs.java
mobile/android/base/toolbar/BrowserToolbar.java
mobile/android/base/toolbar/ToolbarProgressView.java
--- a/mobile/android/base/Tabs.java
+++ b/mobile/android/base/Tabs.java
@@ -51,16 +51,17 @@ public class Tabs implements GeckoEventL
     private final HashMap<Integer, Tab> mTabs = new HashMap<Integer, Tab>();
 
     private AccountManager mAccountManager;
     private OnAccountsUpdateListener mAccountListener = null;
 
     private static final int LOAD_PROGRESS_START = 20;
     private static final int LOAD_PROGRESS_LOCATION_CHANGE = 60;
     private static final int LOAD_PROGRESS_LOADED = 80;
+    private static final int LOAD_PROGRESS_STOP = 100;
 
     public static final int LOADURL_NONE         = 0;
     public static final int LOADURL_NEW_TAB      = 1 << 0;
     public static final int LOADURL_USER_ENTERED = 1 << 1;
     public static final int LOADURL_PRIVATE      = 1 << 2;
     public static final int LOADURL_PINNED       = 1 << 3;
     public static final int LOADURL_DELAY_LOAD   = 1 << 4;
     public static final int LOADURL_DESKTOP      = 1 << 5;
@@ -455,16 +456,17 @@ public class Tabs implements GeckoEventL
                 if ((state & GeckoAppShell.WPL_STATE_IS_NETWORK) != 0) {
                     if ((state & GeckoAppShell.WPL_STATE_START) != 0) {
                         boolean showProgress = message.getBoolean("showProgress");
                         tab.handleDocumentStart(showProgress, message.getString("uri"));
                         tab.setLoadProgress(LOAD_PROGRESS_START);
                         notifyListeners(tab, Tabs.TabEvents.START);
                     } else if ((state & GeckoAppShell.WPL_STATE_STOP) != 0) {
                         tab.handleDocumentStop(message.getBoolean("success"));
+                        tab.setLoadProgress(LOAD_PROGRESS_STOP);
                         notifyListeners(tab, Tabs.TabEvents.STOP);
                     }
                 }
             } else if (event.equals("Content:LoadError")) {
                 tab.setLoadProgress(LOAD_PROGRESS_LOADED);
                 notifyListeners(tab, Tabs.TabEvents.LOAD_ERROR);
             } else if (event.equals("Content:PageShow")) {
                 notifyListeners(tab, TabEvents.PAGE_SHOW);
--- a/mobile/android/base/toolbar/BrowserToolbar.java
+++ b/mobile/android/base/toolbar/BrowserToolbar.java
@@ -466,23 +466,23 @@ public class BrowserToolbar extends Geck
             // Progress-related handling
             switch (msg) {
                 case START:
                     updateProgressVisibility(tab, 0);
                     // Fall through.
                 case LOCATION_CHANGE:
                 case LOAD_ERROR:
                 case LOADED:
+                case STOP:
                     flags.add(UpdateFlags.PROGRESS);
                     if (mProgressBar.getVisibility() == View.VISIBLE) {
                         mProgressBar.animateProgress(tab.getLoadProgress());
                     }
                     break;
 
-                case STOP:
                 case SELECTED:
                     flags.add(UpdateFlags.PROGRESS);
                     updateProgressVisibility();
                     break;
             }
 
             switch (msg) {
                 case STOP:
--- a/mobile/android/base/toolbar/ToolbarProgressView.java
+++ b/mobile/android/base/toolbar/ToolbarProgressView.java
@@ -30,18 +30,19 @@ 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 ImageView {
-    public static final int MAX_PROGRESS = 10000;
-    private static final int MSG_UPDATE = 42;
+    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 Rect mBounds;
     private Handler mHandler;
     private int mCurrentProgress;
@@ -63,25 +64,33 @@ public class ToolbarProgressView extends
 
     private void init(Context ctx) {
         mBounds = new Rect(0,0,0,0);
         mTargetProgress = 0;
 
         mHandler = new Handler() {
             @Override
             public void handleMessage(Message msg) {
-                if (msg.what == MSG_UPDATE) {
-                    final int progress = Math.min(mTargetProgress, mCurrentProgress + mIncrement);
-                    mCurrentProgress = progress;
+                switch (msg.what) {
+                    case MSG_UPDATE:
+                        mCurrentProgress = Math.min(mTargetProgress, mCurrentProgress + mIncrement);
+
+                        updateBounds();
 
-                    updateBounds();
+                        if (mCurrentProgress < mTargetProgress) {
+                            final int delay = (mTargetProgress < MAX_PROGRESS) ? DELAY : DELAY / 4;
+                            sendMessageDelayed(mHandler.obtainMessage(msg.what), delay);
+                        } else if (mCurrentProgress == MAX_PROGRESS) {
+                            sendMessageDelayed(mHandler.obtainMessage(MSG_HIDE), DELAY);
+                        }
+                        break;
 
-                    if (progress < mTargetProgress) {
-                        sendMessageDelayed(mHandler.obtainMessage(MSG_UPDATE), DELAY);
-                    }
+                    case MSG_HIDE:
+                        setVisibility(View.GONE);
+                        break;
                 }
             }
 
         };
     }
 
     @Override
     public void onLayout(boolean f, int l, int t, int r, int b) {
@@ -102,37 +111,45 @@ public class ToolbarProgressView extends
      * Immediately sets the progress bar to the given progress percentage.
      *
      * @param progress Percentage (0-100) to which progress bar should be set
      */
     void setProgress(int progressPercentage) {
         mCurrentProgress = mTargetProgress = getAbsoluteProgress(progressPercentage);
         updateBounds();
 
-        mHandler.removeMessages(MSG_UPDATE);
+        clearMessages();
     }
 
     /**
      * Animates the progress bar from the current progress value to the given
      * progress percentage.
      *
      * @param progress Percentage (0-100) to which progress bar should be animated
      */
     void animateProgress(int progressPercentage) {
         final int absoluteProgress = getAbsoluteProgress(progressPercentage);
-        if (absoluteProgress == mTargetProgress) {
+        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;
         }
 
-        mCurrentProgress = mTargetProgress;
         mTargetProgress = absoluteProgress;
         mIncrement = (mTargetProgress - mCurrentProgress) / STEPS;
 
+        clearMessages();
+        mHandler.sendEmptyMessage(MSG_UPDATE);
+    }
+
+    private void clearMessages() {
         mHandler.removeMessages(MSG_UPDATE);
-        mHandler.sendEmptyMessage(MSG_UPDATE);
+        mHandler.removeMessages(MSG_HIDE);
     }
 
     private int getAbsoluteProgress(int progressPercentage) {
         if (progressPercentage < 0) {
             return 0;
         }
 
         if (progressPercentage > 100) {