Bug 1193745 - Implement the tablet tabs tray grid view on mobile r=mcomella
☠☠ backed out by 49a82a658d1c ☠ ☠
authorMartyn Haigh <mhaigh@mozilla.org>
Thu, 27 Aug 2015 13:09:28 +0100
changeset 292195 159775bbf798b881edd420887faab3f39abe0db1
parent 292194 0077cc462038eaf7cd0c2c16298b0b58b2f9c061
child 292196 ab344226ee3bd04adc09b6809e6eeb01a4b97361
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmcomella
bugs1193745
milestone43.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 1193745 - Implement the tablet tabs tray grid view on mobile r=mcomella
mobile/android/base/BrowserApp.java
mobile/android/base/moz.build
mobile/android/base/resources/layout/private_tabs_panel.xml
mobile/android/base/resources/layout/tabs_layout_item_view.xml
mobile/android/base/resources/layout/tabs_panel_default.xml
mobile/android/base/resources/values-land/dimens.xml
mobile/android/base/resources/values-xlarge-land-v11/dimens.xml
mobile/android/base/resources/values-xlarge-v11/dimens.xml
mobile/android/base/resources/values/dimens.xml
mobile/android/base/resources/values/styles.xml
mobile/android/base/tabs/PrivateTabsPanel.java
mobile/android/base/tabs/TabsGridLayout.java
mobile/android/base/tabs/TabsPanel.java
--- a/mobile/android/base/BrowserApp.java
+++ b/mobile/android/base/BrowserApp.java
@@ -441,18 +441,16 @@ public class BrowserApp extends GeckoApp
         }
     }
 
     @Override
     public View onCreateView(final String name, final Context context, final AttributeSet attrs) {
         final View view;
         if (BrowserToolbar.class.getName().equals(name)) {
             view = BrowserToolbar.create(context, attrs);
-        } else if (TabsPanel.TabsLayout.class.getName().equals(name)) {
-            view = TabsPanel.createTabsLayout(context, attrs);
         } else {
             view = super.onCreateView(name, context, attrs);
         }
         return view;
     }
 
     @Override
     public void onTabChanged(Tab tab, Tabs.TabEvents msg, Object data) {
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -463,17 +463,16 @@ gbjar.sources += [
     'tabs/TabHistoryController.java',
     'tabs/TabHistoryFragment.java',
     'tabs/TabHistoryItemRow.java',
     'tabs/TabHistoryPage.java',
     'tabs/TabPanelBackButton.java',
     'tabs/TabsGridLayout.java',
     'tabs/TabsLayoutAdapter.java',
     'tabs/TabsLayoutItemView.java',
-    'tabs/TabsListLayout.java',
     'tabs/TabsPanel.java',
     'tabs/TabsPanelThumbnailView.java',
     'Telemetry.java',
     'TelemetryContract.java',
     'TextSelection.java',
     'TextSelectionHandle.java',
     'ThumbnailHelper.java',
     'tiles/Tile.java',
--- a/mobile/android/base/resources/layout/private_tabs_panel.xml
+++ b/mobile/android/base/resources/layout/private_tabs_panel.xml
@@ -9,17 +9,17 @@
     <ImageView android:id="@+id/private_tabs_empty"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:src="@drawable/private_masq"
                android:layout_gravity="center"/>
 
     <!-- Note: for an unknown reason, scrolling in the TabsLayout
          does not work unless it is laid out after the empty view. -->
-    <view class="org.mozilla.gecko.tabs.TabsPanel$TabsLayout"
+    <org.mozilla.gecko.tabs.TabsGridLayout
           android:id="@+id/private_tabs_layout"
           style="@style/TabsLayout"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:choiceMode="singleChoice"
           gecko:tabs="tabs_private"/>
 
 </merge>
--- a/mobile/android/base/resources/layout/tabs_layout_item_view.xml
+++ b/mobile/android/base/resources/layout/tabs_layout_item_view.xml
@@ -11,19 +11,19 @@
                                            android:layout_height="wrap_content"
                                            android:gravity="center"
                                            android:orientation="vertical">
 
     <LinearLayout android:layout_width="fill_parent"
                   android:layout_height="wrap_content"
                   android:orientation="horizontal"
                   android:duplicateParentState="true"
-                  android:paddingLeft="@dimen/tablet_tab_highlight_stroke_width"
-                  android:paddingRight="@dimen/tablet_tab_highlight_stroke_width"
-                  android:paddingBottom="@dimen/tablet_tab_highlight_stroke_width">
+                  android:paddingLeft="@dimen/tab_highlight_stroke_width"
+                  android:paddingRight="@dimen/tab_highlight_stroke_width"
+                  android:paddingBottom="@dimen/tab_highlight_stroke_width">
 
        <org.mozilla.gecko.widget.FadedSingleColorTextView
                android:id="@+id/title"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_weight="1.0"
                style="@style/TabLayoutItemTextAppearance"
                android:textSize="14sp"
@@ -57,20 +57,20 @@
 
     </LinearLayout>
 
     <!-- We set state_private on this View dynamically in TabsGridLayout. -->
     <org.mozilla.gecko.widget.TabThumbnailWrapper
             android:id="@+id/wrapper"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:padding="@dimen/tablet_tab_highlight_stroke_width"
+            android:padding="@dimen/tab_highlight_stroke_width"
             android:background="@drawable/tab_thumbnail"
             android:duplicateParentState="true">
 
         <org.mozilla.gecko.tabs.TabsPanelThumbnailView android:id="@+id/thumbnail"
-                                                       android:layout_width="@dimen/tablet_tab_thumbnail_width"
-                                                       android:layout_height="@dimen/tablet_tab_thumbnail_height"
+                                                       android:layout_width="@dimen/tab_thumbnail_width"
+                                                       android:layout_height="@dimen/tab_thumbnail_height"
                                                 />
 
     </org.mozilla.gecko.widget.TabThumbnailWrapper>
 
 </org.mozilla.gecko.tabs.TabsLayoutItemView>
--- a/mobile/android/base/resources/layout/tabs_panel_default.xml
+++ b/mobile/android/base/resources/layout/tabs_panel_default.xml
@@ -61,17 +61,17 @@
 
     </RelativeLayout>
 
     <FrameLayout
           android:id="@+id/tabs_container"
           android:layout_width="match_parent"
           android:layout_height="match_parent">
 
-        <view class="org.mozilla.gecko.tabs.TabsPanel$TabsLayout"
+        <org.mozilla.gecko.tabs.TabsGridLayout
               android:id="@+id/normal_tabs"
               style="@style/TabsLayout"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
               android:choiceMode="singleChoice"
               android:visibility="gone"
               gecko:tabs="tabs_normal"/>
 
--- a/mobile/android/base/resources/values-land/dimens.xml
+++ b/mobile/android/base/resources/values-land/dimens.xml
@@ -4,10 +4,10 @@
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
 <resources>
 
     <!-- Remote Tabs static view top padding. Less in landscape on phones. -->
     <dimen name="home_remote_tabs_top_padding">16dp</dimen>
     <dimen name="page_group_height">64dp</dimen>
 
-    <dimen name="tablet_tab_panel_grid_padding">48dp</dimen>
+    <dimen name="tab_panel_grid_padding">48dp</dimen>
 </resources>
--- a/mobile/android/base/resources/values-xlarge-land-v11/dimens.xml
+++ b/mobile/android/base/resources/values-xlarge-land-v11/dimens.xml
@@ -1,10 +1,10 @@
 <?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/. -->
 
 <resources>
 
-    <dimen name="tablet_tab_panel_grid_padding">64dp</dimen>
+    <dimen name="tab_panel_grid_padding">64dp</dimen>
 
 </resources>
--- a/mobile/android/base/resources/values-xlarge-v11/dimens.xml
+++ b/mobile/android/base/resources/values-xlarge-v11/dimens.xml
@@ -1,11 +1,11 @@
 <?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/. -->
 
 <resources>
 
     <dimen name="panel_grid_view_column_width">250dp</dimen>
-    <dimen name="tablet_tab_panel_grid_padding">48dp</dimen>
+    <dimen name="tab_panel_grid_padding">48dp</dimen>
 
 </resources>
--- a/mobile/android/base/resources/values/dimens.xml
+++ b/mobile/android/base/resources/values/dimens.xml
@@ -125,39 +125,37 @@
     <dimen name="menu_popup_width">256dp</dimen>
     <dimen name="nav_button_border_width">1dp</dimen>
     <dimen name="prompt_service_group_padding_size">32dp</dimen>
     <dimen name="prompt_service_icon_size">36dp</dimen>
     <dimen name="prompt_service_icon_text_padding">10dp</dimen>
     <dimen name="prompt_service_inputs_padding">16dp</dimen>
     <dimen name="prompt_service_left_right_text_with_icon_padding">10dp</dimen>
     <dimen name="prompt_service_top_bottom_text_with_icon_padding">8dp</dimen>
-    <dimen name="tab_thumbnail_height">90dp</dimen>
-    <dimen name="tab_thumbnail_width">160dp</dimen>
     <dimen name="tabs_panel_indicator_width">60dp</dimen>
     <dimen name="tabs_panel_button_width">48dp</dimen>
     <dimen name="tabs_strip_height">48dp</dimen>
     <dimen name="tabs_strip_button_width">100dp</dimen>
     <dimen name="tabs_strip_button_padding">18dp</dimen>
     <dimen name="tabs_strip_shadow_size">1dp</dimen>
     <dimen name="tabs_layout_horizontal_height">156dp</dimen>
     <dimen name="text_selection_handle_width">47dp</dimen>
     <dimen name="text_selection_handle_height">58dp</dimen>
     <dimen name="text_selection_handle_shadow">11dp</dimen>
     <dimen name="validation_message_height">50dp</dimen>
     <dimen name="validation_message_margin_top">6dp</dimen>
 
-    <dimen name="tablet_tab_thumbnail_width">168dp</dimen>
-    <dimen name="tablet_tab_thumbnail_height">140dp</dimen>
-    <dimen name="tablet_tab_panel_column_width">178dp</dimen>
-    <dimen name="tablet_tab_panel_grid_padding">19dp</dimen>
-    <dimen name="tablet_tab_panel_grid_vspacing">21dp</dimen>
-    <dimen name="tablet_tab_panel_grid_padding_top">24dp</dimen>
+    <dimen name="tab_thumbnail_width">121dp</dimen>
+    <dimen name="tab_thumbnail_height">90dp</dimen>
+    <dimen name="tab_panel_column_width">129dp</dimen>
+    <dimen name="tab_panel_grid_padding">20dp</dimen>
+    <dimen name="tab_panel_grid_vspacing">20dp</dimen>
+    <dimen name="tab_panel_grid_padding_top">19dp</dimen>
 
-    <dimen name="tablet_tab_highlight_stroke_width">5dp</dimen>
+    <dimen name="tab_highlight_stroke_width">4dp</dimen>
 
     <!-- PageActionButtons dimensions -->
     <dimen name="page_action_button_width">32dp</dimen>
 
     <!-- Banner -->
     <dimen name="home_banner_height">72dp</dimen>
     <dimen name="home_banner_close_width">42dp</dimen>
     <dimen name="home_banner_icon_height">48dip</dimen>
--- a/mobile/android/base/resources/values/styles.xml
+++ b/mobile/android/base/resources/values/styles.xml
@@ -203,19 +203,19 @@
     <style name="Widget.TabsGridLayout" parent="Widget.GridView">
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">match_parent</item>
         <item name="android:paddingTop">0dp</item>
         <item name="android:stretchMode">spacingWidth</item>
         <item name="android:scrollbarStyle">outsideOverlay</item>
         <item name="android:gravity">center</item>
         <item name="android:numColumns">auto_fit</item>
-        <item name="android:columnWidth">@dimen/tablet_tab_panel_column_width</item>
+        <item name="android:columnWidth">@dimen/tab_panel_column_width</item>
         <item name="android:horizontalSpacing">2dp</item>
-        <item name="android:verticalSpacing">@dimen/tablet_tab_panel_grid_vspacing</item>
+        <item name="android:verticalSpacing">@dimen/tab_panel_grid_vspacing</item>
         <item name="android:drawSelectorOnTop">true</item>
         <item name="android:clipToPadding">false</item>
     </style>
 
     <style name="Widget.BookmarkItemView" parent="Widget.TwoLinePageRow"/>
 
     <style name="Widget.BookmarksListView" parent="Widget.HomeListView"/>
 
--- a/mobile/android/base/tabs/PrivateTabsPanel.java
+++ b/mobile/android/base/tabs/PrivateTabsPanel.java
@@ -8,58 +8,51 @@ package org.mozilla.gecko.tabs;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.tabs.TabsPanel.CloseAllPanelView;
 import org.mozilla.gecko.tabs.TabsPanel.TabsLayout;
 
 import android.content.Context;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.ViewGroup;
 import android.widget.FrameLayout;
-import android.widget.LinearLayout;
 
 /**
  * A container that wraps the private tabs {@link android.widget.AdapterView} and empty
  * {@link android.view.View} to manage both of their visibility states by changing the visibility of
  * this container as calling {@link android.widget.AdapterView#setVisibility} does not affect the
  * empty View's visibility.
  */
 class PrivateTabsPanel extends FrameLayout implements CloseAllPanelView {
     private final TabsLayout tabsLayout;
 
-    public PrivateTabsPanel(Context context, AttributeSet attrs) {
+    public PrivateTabsPanel(final Context context, final AttributeSet attrs) {
         super(context, attrs);
 
         LayoutInflater.from(context).inflate(R.layout.private_tabs_panel, this);
         tabsLayout = (TabsLayout) findViewById(R.id.private_tabs_layout);
 
         final View emptyTabsFrame = findViewById(R.id.private_tabs_empty);
         tabsLayout.setEmptyView(emptyTabsFrame);
     }
 
     @Override
-    public void setTabsPanel(TabsPanel panel) {
+    public void setTabsPanel(final TabsPanel panel) {
         tabsLayout.setTabsPanel(panel);
     }
 
     @Override
     public void show() {
         tabsLayout.show();
         setVisibility(View.VISIBLE);
     }
 
     @Override
     public void hide() {
         setVisibility(View.GONE);
         tabsLayout.hide();
     }
 
     @Override
-    public boolean shouldExpand() {
-        return tabsLayout.shouldExpand();
-    }
-
-    @Override
     public void closeAll() {
         tabsLayout.closeAll();
     }
 }
--- a/mobile/android/base/tabs/TabsGridLayout.java
+++ b/mobile/android/base/tabs/TabsGridLayout.java
@@ -38,65 +38,62 @@ import com.nineoldandroids.animation.Ani
 import com.nineoldandroids.animation.ObjectAnimator;
 import com.nineoldandroids.animation.PropertyValuesHolder;
 import com.nineoldandroids.animation.ValueAnimator;
 
 import java.util.ArrayList;
 import java.util.List;
 
 /**
- * A tabs layout implementation for the tablet redesign (bug 1014156).
- * Expected to replace TabsListLayout once complete.
+ * A tabs layout implementation for the tablet redesign (bug 1014156) and later ported to mobile (bug 1193745).
  */
 
 class TabsGridLayout extends GridView
                      implements TabsLayout,
                                 Tabs.OnTabsChangedListener {
     private static final String LOGTAG = "Gecko" + TabsGridLayout.class.getSimpleName();
 
     public static final int ANIM_DELAY_MULTIPLE_MS = 20;
     private static final int ANIM_TIME_MS = 200;
     private static final DecelerateInterpolator ANIM_INTERPOLATOR = new DecelerateInterpolator();
 
-    private final Context mContext;
-    private final SparseArray<PointF> mTabLocations = new SparseArray<PointF>();
-    private final boolean mIsPrivate;
-    private final TabsLayoutAdapter mTabsAdapter;
-    private final int mColumnWidth;
-    private TabsPanel mTabsPanel;
+    private final SparseArray<PointF> tabLocations = new SparseArray<PointF>();
+    private final boolean isPrivate;
+    private final TabsLayoutAdapter tabsAdapter;
+    private final int columnWidth;
+    private TabsPanel tabsPanel;
     private int lastSelectedTabId;
 
-    public TabsGridLayout(Context context, AttributeSet attrs) {
+    public TabsGridLayout(final Context context, final AttributeSet attrs) {
         super(context, attrs, R.attr.tabGridLayoutViewStyle);
-        mContext = context;
 
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TabsLayout);
-        mIsPrivate = (a.getInt(R.styleable.TabsLayout_tabs, 0x0) == 1);
+        isPrivate = (a.getInt(R.styleable.TabsLayout_tabs, 0x0) == 1);
         a.recycle();
 
-        mTabsAdapter = new TabsGridLayoutAdapter(mContext);
-        setAdapter(mTabsAdapter);
+        tabsAdapter = new TabsGridLayoutAdapter(context);
+        setAdapter(tabsAdapter);
 
         setRecyclerListener(new RecyclerListener() {
             @Override
             public void onMovedToScrapHeap(View view) {
                 TabsLayoutItemView item = (TabsLayoutItemView) view;
                 item.setThumbnail(null);
             }
         });
 
         // The clipToPadding setting in the styles.xml doesn't seem to be working (bug 1101784)
         // so lets set it manually in code for the moment as it's needed for the padding animation
         setClipToPadding(false);
 
         final Resources resources = getResources();
-        mColumnWidth = resources.getDimensionPixelSize(R.dimen.tablet_tab_panel_column_width);
+        columnWidth = resources.getDimensionPixelSize(R.dimen.tab_panel_column_width);
 
-        final int padding = resources.getDimensionPixelSize(R.dimen.tablet_tab_panel_grid_padding);
-        final int paddingTop = resources.getDimensionPixelSize(R.dimen.tablet_tab_panel_grid_padding_top);
+        final int padding = resources.getDimensionPixelSize(R.dimen.tab_panel_grid_padding);
+        final int paddingTop = resources.getDimensionPixelSize(R.dimen.tab_panel_grid_padding_top);
 
         // Lets set double the top padding on the bottom so that the last row shows up properly!
         // Your demise, GridView, cannot come fast enough.
         final int paddingBottom = paddingTop * 2;
 
         setPadding(padding, paddingTop, padding, paddingBottom);
 
         setOnItemClickListener(new OnItemClickListener() {
@@ -109,45 +106,45 @@ class TabsGridLayout extends GridView
         });
 
         TabSwipeGestureListener mSwipeListener = new TabSwipeGestureListener();
         setOnTouchListener(mSwipeListener);
         setOnScrollListener(mSwipeListener.makeScrollListener());
     }
 
     private void populateTabLocations(final Tab removedTab) {
-        mTabLocations.clear();
+        tabLocations.clear();
 
         final int firstPosition = getFirstVisiblePosition();
         final int lastPosition = getLastVisiblePosition();
         final int numberOfColumns = getNumColumns();
         final int childCount = getChildCount();
-        final int removedPosition = mTabsAdapter.getPositionForTab(removedTab);
+        final int removedPosition = tabsAdapter.getPositionForTab(removedTab);
 
         for (int x = 1, i = (removedPosition - firstPosition) + 1; i < childCount; i++, x++) {
             final View child = getChildAt(i);
             if (child != null) {
                 // Reset the transformations here in case the user is swiping tabs away fast and they swipe a tab
                 // before the last animation has finished (bug 1179195).
                 resetTransforms(child);
-                mTabLocations.append(x, new PointF(child.getX(), child.getY()));
+                tabLocations.append(x, new PointF(child.getX(), child.getY()));
             }
         }
 
         final boolean firstChildOffScreen = ((firstPosition > 0) || getChildAt(0).getY() < 0);
         final boolean lastChildVisible = (lastPosition - childCount == firstPosition - 1);
         final boolean oneItemOnLastRow = (lastPosition % numberOfColumns == 0);
         if (firstChildOffScreen && lastChildVisible && oneItemOnLastRow) {
             // We need to set the view's bottom padding to prevent a sudden jump as the
             // last item in the row is being removed. We then need to remove the padding
             // via a sweet animation
 
             final int removedHeight = getChildAt(0).getMeasuredHeight();
             final int verticalSpacing =
-                    getResources().getDimensionPixelOffset(R.dimen.tablet_tab_panel_grid_vspacing);
+                    getResources().getDimensionPixelOffset(R.dimen.tab_panel_grid_vspacing);
 
             ValueAnimator paddingAnimator = ValueAnimator.ofInt(getPaddingBottom() + removedHeight + verticalSpacing, getPaddingBottom());
             paddingAnimator.setDuration(ANIM_TIME_MS * 2);
 
             paddingAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
 
                 @Override
                 public void onAnimationUpdate(ValueAnimator animation) {
@@ -155,68 +152,63 @@ class TabsGridLayout extends GridView
                 }
             });
             paddingAnimator.start();
         }
     }
 
     @Override
     public void setTabsPanel(TabsPanel panel) {
-        mTabsPanel = panel;
+        tabsPanel = panel;
     }
 
     @Override
     public void show() {
         setVisibility(View.VISIBLE);
         Tabs.getInstance().refreshThumbnails();
         Tabs.registerOnTabsChangedListener(this);
         refreshTabsData();
 
         Tab currentlySelectedTab = Tabs.getInstance().getSelectedTab();
         if (lastSelectedTabId != currentlySelectedTab.getId()) {
-            smoothScrollToPosition(mTabsAdapter.getPositionForTab(currentlySelectedTab));
+            smoothScrollToPosition(tabsAdapter.getPositionForTab(currentlySelectedTab));
         }
     }
 
     @Override
     public void hide() {
         lastSelectedTabId = Tabs.getInstance().getSelectedTab().getId();
         setVisibility(View.GONE);
         Tabs.unregisterOnTabsChangedListener(this);
         GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Tab:Screenshot:Cancel", ""));
-        mTabsAdapter.clear();
-    }
-
-    @Override
-    public boolean shouldExpand() {
-        return true;
+        tabsAdapter.clear();
     }
 
     private void autoHidePanel() {
-        mTabsPanel.autoHidePanel();
+        tabsPanel.autoHidePanel();
     }
 
     @Override
     public void onTabChanged(Tab tab, Tabs.TabEvents msg, Object data) {
         switch (msg) {
             case ADDED:
                 // Refresh the list to make sure the new tab is added in the right position.
                 refreshTabsData();
                 break;
 
             case CLOSED:
-                if (mTabsAdapter.getCount() > 0) {
+                if (tabsAdapter.getCount() > 0) {
                     animateRemoveTab(tab);
                 }
 
                 final Tabs tabsInstance = Tabs.getInstance();
 
-                if (mTabsAdapter.removeTab(tab)) {
-                    if (tab.isPrivate() == mIsPrivate && mTabsAdapter.getCount() > 0) {
-                        int selected = mTabsAdapter.getPositionForTab(tabsInstance.getSelectedTab());
+                if (tabsAdapter.removeTab(tab)) {
+                    if (tab.isPrivate() == isPrivate && tabsAdapter.getCount() > 0) {
+                        int selected = tabsAdapter.getPositionForTab(tabsInstance.getSelectedTab());
                         updateSelectedStyle(selected);
                     }
                     if (!tab.isPrivate()) {
                         // Make sure we always have at least one normal tab
                         final Iterable<Tab> tabs = tabsInstance.getTabsInOrder();
                         boolean removedTabIsLastNormalTab = true;
                         for (Tab singleTab : tabs) {
                             if (!singleTab.isPrivate()) {
@@ -235,58 +227,58 @@ class TabsGridLayout extends GridView
                 // Update the selected position, then fall through...
                 updateSelectedPosition();
             case UNSELECTED:
                 // We just need to update the style for the unselected tab...
             case THUMBNAIL:
             case TITLE:
             case RECORDING_CHANGE:
             case AUDIO_PLAYING_CHANGE:
-                View view = getChildAt(mTabsAdapter.getPositionForTab(tab) - getFirstVisiblePosition());
+                View view = getChildAt(tabsAdapter.getPositionForTab(tab) - getFirstVisiblePosition());
                 if (view == null)
                     return;
 
                 ((TabsLayoutItemView) view).assignValues(tab);
                 break;
         }
     }
 
     // Updates the selected position in the list so that it will be scrolled to the right place.
     private void updateSelectedPosition() {
-        int selected = mTabsAdapter.getPositionForTab(Tabs.getInstance().getSelectedTab());
+        int selected = tabsAdapter.getPositionForTab(Tabs.getInstance().getSelectedTab());
         updateSelectedStyle(selected);
 
         if (selected != -1) {
             setSelection(selected);
         }
     }
 
     /**
      * Updates the selected/unselected style for the tabs.
      *
      * @param selected position of the selected tab
      */
     private void updateSelectedStyle(int selected) {
-        for (int i = 0; i < mTabsAdapter.getCount(); i++) {
+        for (int i = 0; i < tabsAdapter.getCount(); i++) {
             setItemChecked(i, (i == selected));
         }
     }
 
     private void refreshTabsData() {
         // Store a different copy of the tabs, so that we don't have to worry about
         // accidentally updating it on the wrong thread.
         ArrayList<Tab> tabData = new ArrayList<>();
 
         Iterable<Tab> allTabs = Tabs.getInstance().getTabsInOrder();
         for (Tab tab : allTabs) {
-            if (tab.isPrivate() == mIsPrivate)
+            if (tab.isPrivate() == isPrivate)
                 tabData.add(tab);
         }
 
-        mTabsAdapter.setTabs(tabData);
+        tabsAdapter.setTabs(tabData);
         updateSelectedPosition();
     }
 
     private void resetTransforms(View view) {
         ViewHelper.setAlpha(view, 1);
         ViewHelper.setTranslationX(view, 0);
         ViewHelper.setTranslationY(view, 0);
 
@@ -301,36 +293,36 @@ class TabsGridLayout extends GridView
         if (getChildCount() == 0) {
             return;
         }
 
         final Iterable<Tab> tabs = Tabs.getInstance().getTabsInOrder();
         for (Tab tab : tabs) {
             // In the normal panel we want to close all tabs (both private and normal),
             // but in the private panel we only want to close private tabs.
-            if (!mIsPrivate || tab.isPrivate()) {
+            if (!isPrivate || tab.isPrivate()) {
                 Tabs.getInstance().closeTab(tab, false);
             }
         }
     }
 
     private View getViewForTab(Tab tab) {
-        final int position = mTabsAdapter.getPositionForTab(tab);
+        final int position = tabsAdapter.getPositionForTab(tab);
         return getChildAt(position - getFirstVisiblePosition());
     }
 
     void closeTab(View v) {
         TabsLayoutItemView itemView = (TabsLayoutItemView) v.getTag();
         Tab tab = Tabs.getInstance().getTab(itemView.getTabId());
 
         Tabs.getInstance().closeTab(tab, true);
     }
 
     private void animateRemoveTab(final Tab removedTab) {
-        final int removedPosition = mTabsAdapter.getPositionForTab(removedTab);
+        final int removedPosition = tabsAdapter.getPositionForTab(removedTab);
 
         final View removedView = getViewForTab(removedTab);
 
         // The removed position might not have a matching child view
         // when it's not within the visible range of positions in the strip.
         if (removedView == null) {
             return;
         }
@@ -353,22 +345,22 @@ class TabsGridLayout extends GridView
 
                 PropertyValuesHolder translateX, translateY;
                 for (int x = 0, i = removedPosition - firstPosition; i < childCount; i++, x++) {
                     final View child = getChildAt(i);
                     ObjectAnimator animator;
 
                     if (i % numberOfColumns == numberOfColumns - 1) {
                         // Animate X & Y
-                        translateX = PropertyValuesHolder.ofFloat("translationX", -(mColumnWidth * numberOfColumns), 0);
+                        translateX = PropertyValuesHolder.ofFloat("translationX", -(columnWidth * numberOfColumns), 0);
                         translateY = PropertyValuesHolder.ofFloat("translationY", removedHeight, 0);
                         animator = ObjectAnimator.ofPropertyValuesHolder(child, translateX, translateY);
                     } else {
                         // Just animate X
-                        translateX = PropertyValuesHolder.ofFloat("translationX", mColumnWidth, 0);
+                        translateX = PropertyValuesHolder.ofFloat("translationX", columnWidth, 0);
                         animator = ObjectAnimator.ofPropertyValuesHolder(child, translateX);
                     }
                     animator.setStartDelay(x * ANIM_DELAY_MULTIPLE_MS);
                     childAnimators.add(animator);
                 }
 
                 final AnimatorSet animatorSet = new AnimatorSet();
                 animatorSet.playTogether(childAnimators);
@@ -377,17 +369,17 @@ class TabsGridLayout extends GridView
                 animatorSet.start();
 
                 // Set the starting position of the child views - because we are delaying the start
                 // of the animation, we need to prevent the items being drawn in their final position
                 // prior to the animation starting
                 for (int x = 1, i = (removedPosition - firstPosition) + 1; i < childCount; i++, x++) {
                     final View child = getChildAt(i);
 
-                    final PointF targetLocation = mTabLocations.get(x + 1);
+                    final PointF targetLocation = tabLocations.get(x + 1);
                     if (targetLocation == null) {
                         continue;
                     }
 
                     child.setX(targetLocation.x);
                     child.setY(targetLocation.y);
                 }
 
@@ -431,17 +423,17 @@ class TabsGridLayout extends GridView
             };
         }
 
         @Override
         TabsLayoutItemView newView(int position, ViewGroup parent) {
             final TabsLayoutItemView item = super.newView(position, parent);
 
             item.setCloseOnClickListener(mCloseClickListener);
-            ((ThemedRelativeLayout) item.findViewById(R.id.wrapper)).setPrivateMode(mIsPrivate);
+            ((ThemedRelativeLayout) item.findViewById(R.id.wrapper)).setPrivateMode(isPrivate);
 
             return item;
         }
 
         @Override
         public void bindView(TabsLayoutItemView view, Tab tab) {
             super.bindView(view, tab);
 
--- a/mobile/android/base/tabs/TabsPanel.java
+++ b/mobile/android/base/tabs/TabsPanel.java
@@ -51,35 +51,26 @@ public class TabsPanel extends LinearLay
         NORMAL_TABS,
         PRIVATE_TABS,
     }
 
     public interface PanelView {
         void setTabsPanel(TabsPanel panel);
         void show();
         void hide();
-        boolean shouldExpand();
     }
 
     public interface CloseAllPanelView extends PanelView {
         void closeAll();
     }
 
     public interface TabsLayout extends CloseAllPanelView {
         void setEmptyView(View view);
     }
 
-    public static View createTabsLayout(final Context context, final AttributeSet attrs) {
-        if (HardwareUtils.isTablet()) {
-            return new TabsGridLayout(context, attrs);
-        } else {
-            return new TabsListLayout(context, attrs);
-        }
-    }
-
     public interface TabsLayoutChangeListener {
         void onTabsLayoutChange(int width, int height);
     }
 
     private final Context mContext;
     private final GeckoApp mActivity;
     private final LightweightTheme mTheme;
     private RelativeLayout mHeader;
@@ -428,20 +419,16 @@ public class TabsPanel extends LinearLay
         mActivity.autoHideTabs();
     }
 
     @Override
     public boolean isShown() {
         return mVisible;
     }
 
-    public Panel getCurrentPanel() {
-        return mCurrentPanel;
-    }
-
     public void setHWLayerEnabled(boolean enabled) {
         if (Versions.preHC) {
             return;
         }
         if (enabled) {
             mHeader.setLayerType(View.LAYER_TYPE_HARDWARE, null);
             mTabsContainer.setLayerType(View.LAYER_TYPE_HARDWARE, null);
         } else {