Bug 970719 - Animate progress bar to end of the screen. r=lucasr
authorBrian Nicholson <bnicholson@mozilla.com>
Wed, 12 Feb 2014 21:47:11 -0800
changeset 168460 be798bbb9163e0d571794f1bc9e0eaddda5fb251
parent 168459 3d831d84bd76145ac5b5b8a248252ab55276e0ef
child 168461 fa91097a7721f04e7ce85854a84e80a732a0a74c
push id26207
push userryanvm@gmail.com
push dateThu, 13 Feb 2014 15:16:01 +0000
treeherdermozilla-central@2ffbe9ab79ea [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslucasr
bugs970719
milestone30.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 970719 - Animate progress bar to end of the screen. r=lucasr
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;
@@ -454,16 +455,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
@@ -470,23 +470,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) {