Bug 893529 - [fig] Allow Tap of reader list icon to open about:home READING LIST page, r=lucasr
authorMark Capella <markcapella@twcny.rr.com>
Mon, 22 Jul 2013 13:49:23 -0400
changeset 143420 3ce8681e56028569c7eef7538ab5b22e8bfcdd5d
parent 143419 57d09922752517a3dc0603a404807c15b0cae08a
child 143421 a985831478dd4dca48de82952cfc5ff92d9d4bc4
push id25130
push userlrocha@mozilla.com
push dateWed, 21 Aug 2013 09:41:27 +0000
treeherdermozilla-central@b2486721572e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslucasr
bugs893529
milestone25.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 893529 - [fig] Allow Tap of reader list icon to open about:home READING LIST page, r=lucasr
mobile/android/base/BrowserApp.java
mobile/android/base/Tab.java
mobile/android/base/Tabs.java
mobile/android/base/home/HomePager.java
mobile/android/chrome/content/browser.js
--- a/mobile/android/base/BrowserApp.java
+++ b/mobile/android/base/BrowserApp.java
@@ -176,17 +176,17 @@ abstract public class BrowserApp extends
             case LOCATION_CHANGE:
                 if (Tabs.getInstance().isSelectedTab(tab)) {
                     maybeCancelFaviconLoad(tab);
                 }
                 // fall through
             case SELECTED:
                 if (Tabs.getInstance().isSelectedTab(tab)) {
                     if (isAboutHome(tab)) {
-                        showHomePager();
+                        showHomePager(tab.getAboutHomePage());
 
                         if (isDynamicToolbarEnabled()) {
                             // Show the toolbar.
                             mLayerView.getLayerMarginsAnimator().showMargins(false);
                         }
                     } else {
                         hideHomePager();
                     }
@@ -461,16 +461,17 @@ abstract public class BrowserApp extends
         registerEventListener("CharEncoding:Data");
         registerEventListener("CharEncoding:State");
         registerEventListener("Feedback:LastUrl");
         registerEventListener("Feedback:OpenPlayStore");
         registerEventListener("Feedback:MaybeLater");
         registerEventListener("Telemetry:Gather");
         registerEventListener("Settings:Show");
         registerEventListener("Updater:Launch");
+        registerEventListener("Reader:GoToReadingList");
 
         Distribution.init(this, getPackageResourcePath());
         JavaAddonManager.getInstance().init(getApplicationContext());
         mSharedPreferencesHelper = new SharedPreferencesHelper(getApplicationContext());
         mOrderedBroadcastHelper = new OrderedBroadcastHelper(getApplicationContext());
         mBrowserHealthReporter = new BrowserHealthReporter();
 
         if (AppConstants.MOZ_ANDROID_BEAM && Build.VERSION.SDK_INT >= 14) {
@@ -730,16 +731,17 @@ abstract public class BrowserApp extends
         unregisterEventListener("CharEncoding:Data");
         unregisterEventListener("CharEncoding:State");
         unregisterEventListener("Feedback:LastUrl");
         unregisterEventListener("Feedback:OpenPlayStore");
         unregisterEventListener("Feedback:MaybeLater");
         unregisterEventListener("Telemetry:Gather");
         unregisterEventListener("Settings:Show");
         unregisterEventListener("Updater:Launch");
+        unregisterEventListener("Reader:GoToReadingList");
 
         if (AppConstants.MOZ_ANDROID_BEAM && Build.VERSION.SDK_INT >= 14) {
             NfcAdapter nfc = NfcAdapter.getDefaultAdapter(this);
             if (nfc != null) {
                 // null this out even though the docs say it's not needed,
                 // because the source code looks like it will only do this
                 // automatically on API 14+
                 nfc.setNdefPushMessageCallback(null, this);
@@ -1090,16 +1092,18 @@ abstract public class BrowserApp extends
                 if (!message.isNull(GeckoPreferences.INTENT_EXTRA_RESOURCES)) {
                     resource = message.getString(GeckoPreferences.INTENT_EXTRA_RESOURCES);
                 }
                 Intent settingsIntent = new Intent(this, GeckoPreferences.class);
                 GeckoPreferences.setResourceToOpen(settingsIntent, resource);
                 startActivity(settingsIntent);
             } else if (event.equals("Updater:Launch")) {
                 handleUpdaterLaunch();
+            } else if (event.equals("Reader:GoToReadingList")) {
+                openReadingList();
             } else {
                 super.handleMessage(event, message);
             }
         } catch (Exception e) {
             Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e);
         }
     }
 
@@ -1243,16 +1247,20 @@ abstract public class BrowserApp extends
         }
 
         Tabs.getInstance().loadUrl(url, searchEngine, -1, flags);
 
         hideBrowserSearch();
         mBrowserToolbar.cancelEdit();
     }
 
+    private void openReadingList() {
+        Tabs.getInstance().loadUrl(ABOUT_HOME, Tabs.LOADURL_READING_LIST);
+    }
+
     /* Favicon methods */
     private void loadFavicon(final Tab tab) {
         maybeCancelFaviconLoad(tab);
 
         int flags = Favicons.FLAG_SCALE | (tab.isPrivate() ? 0 : Favicons.FLAG_PERSIST);
         long id = Favicons.getInstance().loadFavicon(tab.getURL(), tab.getFaviconURL(), flags,
                         new Favicons.OnFaviconLoadedListener() {
 
@@ -1351,39 +1359,39 @@ abstract public class BrowserApp extends
             hideBrowserSearch();
         } else {
             showBrowserSearch();
             mBrowserSearch.filter(searchTerm, handler);
         }
     }
 
     private void animateShowHomePager() {
-        showHomePagerWithAnimation(true);
+        showHomePagerWithAnimation(true, HomePager.Page.BOOKMARKS);
     }
 
-     private void showHomePager() {
-        showHomePagerWithAnimation(false);
+     private void showHomePager(HomePager.Page page) {
+        showHomePagerWithAnimation(false, page);
     }
 
-    private void showHomePagerWithAnimation(boolean animate) {
+    private void showHomePagerWithAnimation(boolean animate, HomePager.Page page) {
         if (mHomePager.isVisible()) {
             return;
         }
 
         // Refresh toolbar height to possibly restore the toolbar padding
         refreshToolbarHeight();
 
         // Show the toolbar before hiding about:home so the
         // onMetricsChanged callback still works.
         if (isDynamicToolbarEnabled() && mLayerView != null) {
             mLayerView.getLayerMarginsAnimator().showMargins(true);
         }
 
         // FIXME: do animation if animate is true
-        mHomePager.show(getSupportFragmentManager());
+        mHomePager.show(getSupportFragmentManager(), page);
     }
 
     private void animateHideHomePager() {
         hideHomePagerWithAnimation(true);
     }
 
     private void hideHomePager() {
         hideHomePagerWithAnimation(false);
--- a/mobile/android/base/Tab.java
+++ b/mobile/android/base/Tab.java
@@ -2,16 +2,17 @@
  * 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;
 
 import org.mozilla.gecko.db.BrowserDB;
 import org.mozilla.gecko.gfx.Layer;
+import org.mozilla.gecko.home.HomePager;
 import org.mozilla.gecko.util.ThreadUtils;
 
 import org.json.JSONException;
 import org.json.JSONObject;
 
 import android.content.ContentResolver;
 import android.content.Context;
 import android.graphics.Bitmap;
@@ -44,16 +45,17 @@ public class Tab {
     private int mFaviconSize;
     private boolean mFeedsEnabled;
     private JSONObject mIdentityData;
     private boolean mReaderEnabled;
     private BitmapDrawable mThumbnail;
     private int mHistoryIndex;
     private int mHistorySize;
     private int mParentId;
+    private HomePager.Page mAboutHomePage;
     private boolean mExternal;
     private boolean mBookmark;
     private boolean mReadingListItem;
     private long mFaviconLoadId;
     private String mDocumentURI;
     private String mContentType;
     private boolean mHasTouchListeners;
     private ZoomConstraints mZoomConstraints;
@@ -79,16 +81,17 @@ public class Tab {
         mAppContext = context.getApplicationContext();
         mId = id;
         mLastUsed = 0;
         mUrl = url;
         mBaseDomain = "";
         mUserSearch = "";
         mExternal = external;
         mParentId = parentId;
+        mAboutHomePage = HomePager.Page.BOOKMARKS;
         mTitle = title == null ? "" : title;
         mFavicon = null;
         mFaviconUrl = null;
         mFaviconSize = 0;
         mFeedsEnabled = false;
         mIdentityData = null;
         mReaderEnabled = false;
         mEnteringReaderMode = false;
@@ -130,16 +133,25 @@ public class Tab {
     public synchronized long getLastUsed() {
         return mLastUsed;
     }
 
     public int getParentId() {
         return mParentId;
     }
 
+    public HomePager.Page getAboutHomePage() {
+        return mAboutHomePage;
+    }
+
+    private void setAboutHomePage(HomePager.Page page) {
+        mAboutHomePage = page;
+    }
+
+
     // may be null if user-entered query hasn't yet been resolved to a URI
     public synchronized String getURL() {
         return mUrl;
     }
 
     // mUserSearch should never be null, but it may be an empty string
     public synchronized String getUserSearch() {
         return mUserSearch;
@@ -590,16 +602,21 @@ public class Tab {
         setFeedsEnabled(false);
         updateTitle(null);
         updateIdentityData(null);
         setReaderEnabled(false);
         setZoomConstraints(new ZoomConstraints(true));
         setHasTouchListeners(false);
         setBackgroundColor(DEFAULT_BACKGROUND_COLOR);
 
+        final String homePage = message.getString("aboutHomePage");
+        if (!TextUtils.isEmpty(homePage)) {
+            setAboutHomePage(HomePager.Page.valueOf(homePage));
+        }
+
         Tabs.getInstance().notifyListeners(this, Tabs.TabEvents.LOCATION_CHANGE, uri);
     }
 
     private boolean shouldShowProgress(String url) {
         return "about:home".equals(url) || ReaderModeUtils.isAboutReader(url);
     }
 
     void handleDocumentStart(boolean showProgress, String url) {
--- a/mobile/android/base/Tabs.java
+++ b/mobile/android/base/Tabs.java
@@ -1,16 +1,17 @@
 /* -*- 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;
 
 import org.mozilla.gecko.db.BrowserDB;
+import org.mozilla.gecko.home.HomePager;
 import org.mozilla.gecko.sync.setup.SyncAccounts;
 import org.mozilla.gecko.util.GeckoEventListener;
 import org.mozilla.gecko.util.ThreadUtils;
 
 import org.json.JSONObject;
 
 import android.accounts.Account;
 import android.accounts.AccountManager;
@@ -52,16 +53,17 @@ public class Tabs implements GeckoEventL
     public static final int LOADURL_NONE = 0;
     public static final int LOADURL_NEW_TAB = 1;
     public static final int LOADURL_USER_ENTERED = 2;
     public static final int LOADURL_PRIVATE = 4;
     public static final int LOADURL_PINNED = 8;
     public static final int LOADURL_DELAY_LOAD = 16;
     public static final int LOADURL_DESKTOP = 32;
     public static final int LOADURL_BACKGROUND = 64;
+    public static final int LOADURL_READING_LIST = 128;
 
     private static final long PERSIST_TABS_AFTER_MILLISECONDS = 1000 * 5;
 
     private static AtomicInteger sTabId = new AtomicInteger(0);
     private volatile boolean mInitialTabsAdded;
 
     private Context mAppContext;
     private ContentObserver mContentObserver;
@@ -645,16 +647,17 @@ public class Tabs implements GeckoEventL
             args.put("parentId", parentId);
             args.put("userEntered", userEntered);
             args.put("newTab", (flags & LOADURL_NEW_TAB) != 0);
             args.put("isPrivate", isPrivate);
             args.put("pinned", (flags & LOADURL_PINNED) != 0);
             args.put("delayLoad", delayLoad);
             args.put("desktopMode", desktopMode);
             args.put("selected", !background);
+            args.put("aboutHomePage", (flags & LOADURL_READING_LIST) != 0 ? HomePager.Page.READING_LIST : "");
 
             if ((flags & LOADURL_NEW_TAB) != 0) {
                 int tabId = getNextTabId();
                 args.put("tabID", tabId);
 
                 // The URL is updated for the tab once Gecko responds with the
                 // Tab:Added message. We can preliminarily set the tab's URL as
                 // long as it's a valid URI.
--- a/mobile/android/base/home/HomePager.java
+++ b/mobile/android/base/home/HomePager.java
@@ -23,17 +23,17 @@ import java.util.EnumSet;
 public class HomePager extends ViewPager {
     // Subpage fragment tag
     public static final String SUBPAGE_TAG = "home_pager_subpage";
 
     private final Context mContext;
     private volatile boolean mLoaded;
 
     // List of pages in order.
-    private enum Page {
+    public enum Page {
         VISITED,
         BOOKMARKS,
         READING_LIST
     }
 
     private EnumMap<Page, Fragment> mPages = new EnumMap<Page, Fragment>(Page.class);
 
     public interface OnUrlOpenListener {
@@ -54,29 +54,28 @@ public class HomePager extends ViewPager
         mContext = context;
     }
 
     /**
      * Loads and initializes the pager.
      *
      * @param fm FragmentManager for the adapter
      */
-    public void show(FragmentManager fm) {
+    public void show(FragmentManager fm, Page page) {
         mLoaded = true;
         TabsAdapter adapter = new TabsAdapter(fm);
 
         // Add the pages to the adapter in order.
         adapter.addTab(Page.VISITED, VisitedPage.class, null, getContext().getString(R.string.visited_title));
         adapter.addTab(Page.BOOKMARKS, BookmarksPage.class, null, getContext().getString(R.string.bookmarks_title));
         adapter.addTab(Page.READING_LIST, ReadingListPage.class, null, getContext().getString(R.string.reading_list));
 
         setAdapter(adapter);
 
-        // Set the bookmarks page as the landing page.
-        setCurrentItem(1, false);
+        setCurrentItem(adapter.getItemPosition(page), false);
         setVisibility(VISIBLE);
     }
 
     /**
      * Hides the pager and removes all child fragments.
      */
     public void hide() {
         mLoaded = false;
@@ -118,16 +117,27 @@ public class HomePager extends ViewPager
         }
 
         public void addTab(Page page, Class<?> clss, Bundle args, String title) {
             TabInfo info = new TabInfo(page, clss, args, title);
             mTabs.add(info);
             notifyDataSetChanged();
         }
 
+        public int getItemPosition(Page page) {
+            for (int i = 0; i < mTabs.size(); i++) {
+                TabInfo info = mTabs.get(i);
+                if (info.page == page) {
+                    return i;
+                }
+            }
+
+            return -1;
+        }
+
         @Override
         public int getCount() {
             return mTabs.size();
         }
 
         @Override
         public Fragment getItem(int position) {
             TabInfo info = mTabs.get(position);
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -760,28 +760,26 @@ var BrowserApp = {
 
     aParams = aParams || {};
 
     let flags = "flags" in aParams ? aParams.flags : Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
     let postData = ("postData" in aParams && aParams.postData) ? aParams.postData : null;
     let referrerURI = "referrerURI" in aParams ? aParams.referrerURI : null;
     let charset = "charset" in aParams ? aParams.charset : null;
 
-    if ("showProgress" in aParams || "userSearch" in aParams) {
-      let tab = this.getTabForBrowser(aBrowser);
-      if (tab) {
-        if ("showProgress" in aParams) tab.showProgress = aParams.showProgress;
-        if ("userSearch" in aParams) tab.userSearch = aParams.userSearch;
-      }
+    let tab = this.getTabForBrowser(aBrowser);
+    if (tab) {
+      if (!tab.aboutHomePage) tab.aboutHomePage = ("aboutHomePage" in aParams) ? aParams.aboutHomePage : "";
+      if ("showProgress" in aParams) tab.showProgress = aParams.showProgress;
+      if ("userSearch" in aParams) tab.userSearch = aParams.userSearch;
     }
 
     try {
       aBrowser.loadURIWithFlags(aURI, flags, referrerURI, charset, postData);
     } catch(e) {
-      let tab = this.getTabForBrowser(aBrowser);
       if (tab) {
         let message = {
           type: "Content:LoadError",
           tabID: tab.id
         };
         sendMessageToJava(message);
         dump("Handled load error: " + e)
       }
@@ -1371,16 +1369,17 @@ var BrowserApp = {
 
         let delayLoad = ("delayLoad" in data) ? data.delayLoad : false;
         let params = {
           selected: ("selected" in data) ? data.selected : !delayLoad,
           parentId: ("parentId" in data) ? data.parentId : -1,
           flags: flags,
           tabID: data.tabID,
           isPrivate: (data.isPrivate === true),
+          aboutHomePage: ("aboutHomePage" in data) ? data.aboutHomePage : "",
           pinned: (data.pinned === true),
           delayLoad: (delayLoad === true),
           desktopMode: (data.desktopMode === true)
         };
 
         let url = data.url;
         if (data.engine) {
           let engine = Services.search.getEngineByName(data.engine);
@@ -2527,16 +2526,17 @@ function Tab(aURL, aParams) {
   this.viewportMeasureCallback = null;
   this.lastPageSizeUsedForViewportChange = { width: 0, height: 0 };
   this.contentDocumentIsDisplayed = true;
   this.pluginDoorhangerTimeout = null;
   this.shouldShowPluginDoorhanger = true;
   this.clickToPlayPluginsActivated = false;
   this.desktopMode = false;
   this.originalURI = null;
+  this.aboutHomePage = null;
   this.savedArticle = null;
   this.hasTouchListener = false;
   this.browserWidth = 0;
   this.browserHeight = 0;
 
   this.create(aURL, aParams);
 }
 
@@ -3631,16 +3631,17 @@ Tab.prototype = {
     }
 
     let message = {
       type: "Content:LocationChange",
       tabID: this.id,
       uri: fixedURI.spec,
       userSearch: this.userSearch || "",
       documentURI: documentURI,
+      aboutHomePage: this.aboutHomePage || "",
       baseDomain: baseDomain,
       contentType: (contentType ? contentType : ""),
       sameDocument: sameDocument
     };
 
     sendMessageToJava(message);
 
     // The search term is only valid for this location change event, so reset it here.