Bug 817706: Tab-style switcher in tabs-tray for phones. [r=mfinkle]
authorSriram Ramasubramanian <sriram@mozilla.com>
Tue, 18 Dec 2012 17:04:39 -0800
changeset 116723 296cc3ea6e9e4cec791933e481aef825760a6430
parent 116722 93e12399bae42c6a3aa28637e2fe438755feb89a
child 116724 7998f3adb4c5ba142c65e0759b7779b9ed05c3de
push id24072
push userMs2ger@gmail.com
push dateSat, 22 Dec 2012 13:18:22 +0000
treeherdermozilla-central@ea373e534245 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle
bugs817706
milestone20.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 817706: Tab-style switcher in tabs-tray for phones. [r=mfinkle]
mobile/android/base/BrowserApp.java
mobile/android/base/BrowserToolbar.java
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoViewsFactory.java
mobile/android/base/Makefile.in
mobile/android/base/TabsPanel.java
mobile/android/base/locales/en-US/android_strings.dtd
mobile/android/base/resources/drawable/tabs_panel_indicator.xml
mobile/android/base/resources/layout-land-v14/tabs_panel_toolbar_menu.xml
mobile/android/base/resources/layout-large-v11/tabs_panel_toolbar_menu.xml
mobile/android/base/resources/layout-xlarge-v11/tabs_panel_toolbar_menu.xml
mobile/android/base/resources/layout/gecko_app.xml.in
mobile/android/base/resources/layout/tabs_panel.xml
mobile/android/base/resources/layout/tabs_panel.xml.in
mobile/android/base/resources/layout/tabs_panel_indicator.xml
mobile/android/base/resources/layout/tabs_panel_toolbar_menu.xml
mobile/android/base/strings.xml.in
--- a/mobile/android/base/BrowserApp.java
+++ b/mobile/android/base/BrowserApp.java
@@ -494,18 +494,22 @@ abstract public class BrowserApp extends
             Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e);
         }
     }
 
     void addTab() {
         showAwesomebar(AwesomeBar.Target.NEW_TAB);
     }
 
-    public void showLocalTabs() {
-        showTabs(TabsPanel.Panel.LOCAL_TABS);
+    public void showNormalTabs() {
+        showTabs(TabsPanel.Panel.NORMAL_TABS);
+    }
+
+    public void showPrivateTabs() {
+        showTabs(TabsPanel.Panel.PRIVATE_TABS);
     }
 
     public void showRemoteTabs() {
         showTabs(TabsPanel.Panel.REMOTE_TABS);
     }
 
     private void showTabs(TabsPanel.Panel panel) {
         if (Tabs.getInstance().getCount() == 0)
--- a/mobile/android/base/BrowserToolbar.java
+++ b/mobile/android/base/BrowserToolbar.java
@@ -685,17 +685,24 @@ public class BrowserToolbar implements V
         if (mActivity.areTabsShown()) {
             if (mActivity.hasTabsSideBar())
                 mActivity.hideTabs();
         } else {
             // hide the virtual keyboard
             InputMethodManager imm =
                     (InputMethodManager) mActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
             imm.hideSoftInputFromWindow(mTabs.getWindowToken(), 0);
-            mActivity.showLocalTabs();
+
+            Tab tab = Tabs.getInstance().getSelectedTab();
+            if (tab != null) {
+                if (!tab.isPrivate())
+                    mActivity.showNormalTabs();
+                else
+                    mActivity.showPrivateTabs();
+            }
         }
     }
 
     public void updateTabCountAndAnimate(int count) {
         if (mCount > count) {
             mTabsCount.setInAnimation(mSlideDownIn);
             mTabsCount.setOutAnimation(mSlideDownOut);
         } else if (mCount < count) {
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -799,17 +799,19 @@ abstract public class GeckoApp
             Log.i(LOGTAG, "Startup mode: " + mStartupMode);
 
             return mStartupMode;
         }
     }
 
     void addTab() { }
 
-    public void showLocalTabs() { }
+    public void showNormalTabs() { }
+
+    public void showPrivateTabs() { }
 
     public void showRemoteTabs() { }
 
     private void showTabs(TabsPanel.Panel panel) { }
 
     public void hideTabs() { }
 
     /**
--- a/mobile/android/base/GeckoViewsFactory.java
+++ b/mobile/android/base/GeckoViewsFactory.java
@@ -73,22 +73,26 @@ public final class GeckoViewsFactory imp
             else if (TextUtils.equals(viewName, "GeckoApp$MainLayout"))
                 return new GeckoApp.MainLayout(context, attrs);
             else if (TextUtils.equals(viewName, "LinkTextView"))
                 return new LinkTextView(context, attrs);
             else if (TextUtils.equals(viewName, "FindInPageBar"))
                 return new FindInPageBar(context, attrs);
             else if (TextUtils.equals(viewName, "MenuButton"))
                 return new MenuButton(context, attrs);
+            else if (TextUtils.equals(viewName, "RemoteTabs"))
+                return new RemoteTabs(context, attrs);
             else if (TextUtils.equals(viewName, "TabsButton"))
                 return new TabsButton(context, attrs);
             else if (TextUtils.equals(viewName, "TabsPanel"))
                 return new TabsPanel(context, attrs);
             else if (TextUtils.equals(viewName, "TabsPanelButton"))
                 return new TabsPanelButton(context, attrs);
+            else if (TextUtils.equals(viewName, "TabsTray"))
+                return new TabsTray(context, attrs);
             else if (TextUtils.equals(viewName, "TextSelectionHandle"))
                 return new TextSelectionHandle(context, attrs);
             else if (TextUtils.equals(viewName, "gfx.LayerView"))
                 return new LayerView(context, attrs);
             else if (TextUtils.equals(viewName, "Button"))
                 return new GeckoButton(context, attrs);
             else if (TextUtils.equals(viewName, "EditText"))
                 return new GeckoEditText(context, attrs);
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -244,16 +244,17 @@ FENNEC_PP_XML_FILES = \
   res/layout/browser_toolbar.xml \
   res/layout/browser_toolbar_menu.xml \
   res/layout-land-v14/browser_toolbar.xml \
   res/layout-land-v14/browser_toolbar_menu.xml \
   res/layout-large-v11/awesomebar_search.xml \
   res/layout-large-v11/browser_toolbar_menu.xml \
   res/layout-xlarge-v11/browser_toolbar_menu.xml \
   res/layout/gecko_app.xml \
+  res/layout/tabs_panel.xml \
   res/layout/text_selection_handles.xml \
   res/layout-xlarge-land-v11/abouthome_content.xml \
   res/layout-xlarge-v11/awesomebar_search.xml \
   res/layout-xlarge-v11/gecko_app.xml \
   res/xml/preferences.xml \
   res/xml/searchable.xml \
   res/menu/browser_app_menu.xml \
   res/menu-v11/browser_app_menu.xml \
@@ -400,17 +401,17 @@ RES_LAYOUT = \
   res/layout/site_setting_title.xml \
   res/layout/setup_screen.xml \
   res/layout/shared_ui_components.xml \
   res/layout/site_identity_popup.xml \
   res/layout/remote_tabs.xml \
   res/layout/remote_tabs_child.xml \
   res/layout/remote_tabs_group.xml \
   res/layout/tabs_counter.xml \
-  res/layout/tabs_panel.xml \
+  res/layout/tabs_panel_indicator.xml \
   res/layout/tabs_panel_toolbar_menu.xml \
   res/layout/tabs_row.xml \
   res/layout/tabs_tray.xml \
   res/layout/list_item_header.xml \
   res/layout/select_dialog_list.xml \
   res/layout/select_dialog_multichoice.xml \
   res/layout/abouthome_addon_row.xml \
   res/layout/abouthome_last_tabs_row.xml \
@@ -1058,16 +1059,17 @@ MOZ_ANDROID_DRAWABLES += \
   mobile/android/base/resources/drawable/progress_spinner_12.png                \
   mobile/android/base/resources/drawable/remote_tabs_level.xml                  \
   mobile/android/base/resources/drawable/start.png                              \
   mobile/android/base/resources/drawable/site_security_level.xml                \
   mobile/android/base/resources/drawable/suggestion_selector.xml                \
   mobile/android/base/resources/drawable/tab_new_button.xml                     \
   mobile/android/base/resources/drawable/tabs_button.xml                        \
   mobile/android/base/resources/drawable/tabs_level.xml                         \
+  mobile/android/base/resources/drawable/tabs_panel_indicator.xml               \
   mobile/android/base/resources/drawable/tabs_tray_bg_repeat.xml                \
   mobile/android/base/resources/drawable/tabs_tray_selected_bg_repeat.xml       \
   mobile/android/base/resources/drawable/tabs_tray_active_selector.xml          \
   mobile/android/base/resources/drawable/tabs_tray_default_selector.xml         \
   mobile/android/base/resources/drawable/tabs_tray_list_divider.xml             \
   mobile/android/base/resources/drawable/tabs_shadow.xml                        \
   mobile/android/base/resources/drawable/shadow.png                             \
   mobile/android/base/resources/drawable/marketplace.png                        \
--- a/mobile/android/base/TabsPanel.java
+++ b/mobile/android/base/TabsPanel.java
@@ -16,28 +16,33 @@ import android.graphics.drawable.ColorDr
 import android.graphics.drawable.LayerDrawable;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.Button;
+import android.widget.FrameLayout;
 import android.widget.ImageButton;
 import android.widget.LinearLayout;
 import android.widget.RelativeLayout;
+import android.widget.TabHost;
+import android.widget.TabHost.TabSpec;
+import android.widget.TabWidget;
 import android.widget.TextView;
 
-public class TabsPanel extends LinearLayout
+public class TabsPanel extends TabHost
                        implements GeckoPopupMenu.OnMenuItemClickListener,
                                   LightweightTheme.OnChangeListener {
     private static final String LOGTAG = "GeckoTabsPanel";
 
     public static enum Panel {
-        LOCAL_TABS,
+        NORMAL_TABS,
+        PRIVATE_TABS,
         REMOTE_TABS
     }
 
     public static interface PanelView {
         public ViewGroup getLayout();
         public void setTabsPanel(TabsPanel panel);
         public void show();
         public void hide();
@@ -46,80 +51,123 @@ public class TabsPanel extends LinearLay
     public static interface TabsLayoutChangeListener {
         public void onTabsLayoutChange(int width, int height);
     }
 
     private Context mContext;
     private GeckoApp mActivity;
     private PanelView mPanel;
     private TabsPanelToolbar mToolbar;
-    private TabsListContainer mListContainer;
     private TabsLayoutChangeListener mLayoutChangeListener;
 
     private static ImageButton mMenuButton;
     private static ImageButton mAddTab;
-    private static ImageButton mRemoteTabs;
-    private TextView mTitle;
+    private TabWidget mTabWidget;
 
     private Panel mCurrentPanel;
     private boolean mIsSideBar;
     private boolean mVisible;
+    private boolean mInflated;
 
     private GeckoPopupMenu mPopupMenu;
     private Menu mMenu;
 
     private static final int REMOTE_TABS_HIDDEN = 1;
     private static final int REMOTE_TABS_SHOWN = 2;
 
     public TabsPanel(Context context, AttributeSet attrs) {
         super(context, attrs);
         mContext = context;
         mActivity = (GeckoApp) context;
 
-        setOrientation(LinearLayout.VERTICAL);
-        LayoutInflater.from(context).inflate(R.layout.tabs_panel, this);
-
-        mCurrentPanel = Panel.LOCAL_TABS;
+        mCurrentPanel = Panel.NORMAL_TABS;
         mVisible = false;
 
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TabsPanel);
         mIsSideBar = a.getBoolean(R.styleable.TabsPanel_sidebar, false);
         a.recycle();
 
-        mToolbar = (TabsPanelToolbar) findViewById(R.id.toolbar);
-        mListContainer = (TabsListContainer) findViewById(R.id.list_container);
-
         mPopupMenu = new GeckoPopupMenu(context);
         mPopupMenu.inflate(R.menu.tabs_menu);
         mPopupMenu.setOnMenuItemClickListener(this);
         mMenu = mPopupMenu.getMenu();
 
+        LayoutInflater.from(context).inflate(R.layout.tabs_panel, this);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+
+        // HACK: Without this, the onFinishInflate is called twice
+        // This issue is due to a bug when Android inflates a layout with a
+        // parent. Fixed in Honeycomb
+        if (mInflated)
+            return;
+
+        mInflated = true;
+
+        initialize();
+    }
+
+    private void initialize() {
+        // This should be called before adding any tabs
+        // to the TabHost.
+        setup();
+
         initToolbar();
+        addTab(R.string.tabs_normal, R.id.normal_tabs);
+        addTab(R.string.tabs_private, R.id.private_tabs);
+        addTab(R.string.tabs_synced, R.id.synced_tabs);
+    }
+
+    private void addTab(int resId, int contentId) {
+        String title = mContext.getString(resId);
+        TabSpec spec = newTabSpec(title);
+        GeckoTextView indicatorView = (GeckoTextView) LayoutInflater.from(mContext).inflate(R.layout.tabs_panel_indicator, null);
+        indicatorView.setText(title);
+
+        spec.setIndicator(indicatorView);
+        spec.setContent(contentId);
+
+        final int index = mTabWidget.getTabCount();
+        PanelView panel = (PanelView) findViewById(contentId);
+        panel.setTabsPanel(this);
+        panel.show();
+
+        addTab(spec);
+
+        indicatorView.setOnClickListener(new View.OnClickListener() {
+            public void onClick(View v) {
+                Panel panel = Panel.NORMAL_TABS;
+                if (index == 1)
+                    panel = Panel.PRIVATE_TABS;
+                else if (index == 2)
+                    panel = Panel.REMOTE_TABS;
+
+                TabsPanel.this.show(panel);
+            }
+        });
     }
 
     void initToolbar() {
-        mTitle = (TextView) mToolbar.findViewById(R.id.title);
+        mToolbar = (TabsPanelToolbar) findViewById(R.id.toolbar);
+
+        mTabWidget = (TabWidget) findViewById(android.R.id.tabs);
+        mTabWidget.setDividerDrawable(null);
+        mTabWidget.setStripEnabled(false);
+
         mAddTab = (ImageButton) mToolbar.findViewById(R.id.add_tab);
         mAddTab.setOnClickListener(new Button.OnClickListener() {
             public void onClick(View v) {
                 mActivity.addTab();
                 mActivity.autoHideTabs();
             }
         });
 
-        mRemoteTabs = (ImageButton) mToolbar.findViewById(R.id.remote_tabs);
-        mRemoteTabs.setOnClickListener(new Button.OnClickListener() {
-            public void onClick(View v) {
-                if (mRemoteTabs.getDrawable().getLevel() == REMOTE_TABS_SHOWN)
-                    mActivity.showLocalTabs();
-                else
-                    mActivity.showRemoteTabs();
-            }
-        });
-
         mMenuButton = (ImageButton) mToolbar.findViewById(R.id.menu);
         mMenuButton.setOnClickListener(new Button.OnClickListener() {
             public void onClick(View view) {
                 TabsPanel.this.openTabsMenu();
             }
         });
 
         // Set a touch delegate to Add-Tab button, so the touch events on its tail
@@ -235,17 +283,17 @@ public class TabsPanel extends LinearLay
 
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
         onLightweightThemeChanged();
     }
 
     // Tabs List Container holds the ListView
-    public static class TabsListContainer extends LinearLayout {
+    public static class TabsListContainer extends FrameLayout {
         private Context mContext;
 
         public TabsListContainer(Context context, AttributeSet attrs) {
             super(context, attrs);
             mContext = context;
         }
 
         @Override
@@ -267,16 +315,18 @@ public class TabsPanel extends LinearLay
         public TabsPanelToolbar(Context context, AttributeSet attrs) {
             super(context, attrs);
             mActivity = (BrowserApp) context;
 
             setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,
                                                           (int) context.getResources().getDimension(R.dimen.browser_toolbar_height)));
 
             LayoutInflater.from(context).inflate(R.layout.tabs_panel_toolbar_menu, this);
+            TabWidget tabWidget = (TabWidget) findViewById(android.R.id.tabs);
+            tabWidget.setStripEnabled(false);
         }
 
         @Override
         public void onAttachedToWindow() {
             super.onAttachedToWindow();
             mActivity.getLightweightTheme().addListener(this);
         }
 
@@ -305,85 +355,54 @@ public class TabsPanel extends LinearLay
         protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
             super.onLayout(changed, left, top, right, bottom);
             onLightweightThemeChanged();
         }
     }
 
     public void show(Panel panel) {
         if (mPanel != null) {
-            // Remove the old panel.
+            // Hide the old panel.
             mPanel.hide();
-            mListContainer.removeAllViews();
         }
 
         final boolean showAnimation = !mVisible;
         mVisible = true;
         mCurrentPanel = panel;
 
-        if (panel == Panel.LOCAL_TABS) {
-            mPanel = new TabsTray(mContext, null);
-            mTitle.setText("");
-            mRemoteTabs.setImageLevel(REMOTE_TABS_HIDDEN);
-        } else {
-            mPanel = new RemoteTabs(mContext, null);
-            mTitle.setText(R.string.remote_tabs);
-            mRemoteTabs.setVisibility(View.VISIBLE);
-            mRemoteTabs.setImageLevel(REMOTE_TABS_SHOWN);
-        }
+        int index = panel.ordinal();
+        setCurrentTab(index);
 
-        mPanel.setTabsPanel(this);
+        mPanel = (PanelView) getTabContentView().getChildAt(index);
         mPanel.show();
-        mListContainer.addView(mPanel.getLayout());
 
         if (isSideBar()) {
             if (showAnimation)
                 dispatchLayoutChange(getWidth(), getHeight());
         } else {
             int actionBarHeight = mContext.getResources().getDimensionPixelSize(R.dimen.browser_toolbar_height);
-            int height = actionBarHeight + getTabContainerHeight(mListContainer);
+            int height = actionBarHeight + getTabContainerHeight(getTabContentView());
             dispatchLayoutChange(getWidth(), height);
         }
-
-        // If Sync is set up, query the database for remote clients.
-        final Context context = mContext;
-        new SyncAccounts.AccountsExistTask() {
-            @Override
-            protected void onPostExecute(Boolean result) {
-                if (!result.booleanValue()) {
-                    return;
-                }
-                TabsAccessor.areClientsAvailable(context, new TabsAccessor.OnClientsAvailableListener() {
-                    @Override
-                    public void areAvailable(boolean available) {
-                        final int visibility = available ? View.VISIBLE : View.GONE;
-                        mRemoteTabs.setVisibility(visibility);
-                    }
-                });
-            }
-        }.execute(context);
     }
 
     public void hide() {
         if (mVisible) {
             mVisible = false;
             mPopupMenu.dismiss();
             dispatchLayoutChange(0, 0);
         }
     }
 
     public void refresh() {
-        mListContainer.forceLayout();
+        clearAllTabs();
+        removeAllViews();
 
-        int index = indexOfChild(mToolbar);
-        removeViewAt(index);
-
-        mToolbar = new TabsPanelToolbar(mContext, null);
-        addView(mToolbar, index);
-        initToolbar();
+        LayoutInflater.from(mContext).inflate(R.layout.tabs_panel, this);
+        initialize();
 
         if (mVisible)
             show(mCurrentPanel);
     }
 
     public void autoHidePanel() {
         mActivity.autoHideTabs();
     }
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -134,16 +134,19 @@ size. -->
 <!ENTITY save_as_pdf "Save as PDF">
 <!ENTITY find_in_page "Find in Page">
 <!ENTITY desktop_mode "Request Desktop Site">
 <!ENTITY tools "Tools">
 <!ENTITY new_tab "New Tab">
 <!ENTITY new_private_tab "New Private Tab">
 <!ENTITY synced_tabs "Synced Tabs">
 <!ENTITY close_all_tabs "Close All Tabs">
+<!ENTITY tabs_normal "Tabs">
+<!ENTITY tabs_private "Private">
+<!ENTITY tabs_synced "Synced">
 <!ENTITY wallpaper_success "Wallpaper updated">
 <!ENTITY wallpaper_progress "Setting wallpaper">
 <!ENTITY wallpaper_fail "Unable to set wallpaper">
 
 <!-- Localization note (find_text, find_prev, find_next, find_close) : These strings are used
      as alternate text for accessibility. They are not visible in the UI. -->
 <!ENTITY find_text "Find in Page">
 <!ENTITY find_prev "Previous">
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/resources/drawable/tabs_panel_indicator.xml
@@ -0,0 +1,12 @@
+<?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">
+
+    <item android:state_selected="false" android:drawable="@android:color/transparent"/>
+
+    <item android:state_selected="true" android:drawable="@drawable/highlight"/>
+
+</selector>
--- a/mobile/android/base/resources/layout-land-v14/tabs_panel_toolbar_menu.xml
+++ b/mobile/android/base/resources/layout-land-v14/tabs_panel_toolbar_menu.xml
@@ -19,34 +19,21 @@
                                       android:paddingLeft="35dip"
                                       android:paddingRight="10dip"
                                       android:enabled="false"/>
 
         <LinearLayout android:layout_width="fill_parent"
                       android:layout_height="fill_parent"
                       android:layout_marginRight="15dip">
 
-            <TextView android:id="@+id/title"
-                      android:layout_width="wrap_content"
-                      android:layout_height="fill_parent"
-                      android:layout_weight="1.0"
-                      style="@style/TabRowTextAppearance"
-                      android:gravity="center_vertical"
-                      android:padding="10dip"
-                      android:textSize="13sp"/>
+            <TabWidget android:id="@android:id/tabs"
+                       android:layout_width="0dip"
+                       android:layout_height="fill_parent"
+                       android:layout_weight="1.0"/>
 
-            <ImageButton android:id="@+id/remote_tabs"
-                         android:layout_width="@dimen/browser_toolbar_height"
-                         android:layout_height="@dimen/browser_toolbar_height"
-                         android:gravity="center_vertical"
-                         android:padding="10dip"
-                         android:src="@drawable/remote_tabs_level"
-                         android:contentDescription="@string/remote_tabs"
-                         android:background="@drawable/action_bar_button"
-                         android:visibility="gone"/>
 
             <org.mozilla.gecko.TabsPanelButton android:id="@+id/add_tab"
                                                android:layout_width="63dip"
                                                android:layout_height="@dimen/browser_toolbar_height"
                                                android:gravity="center_vertical"
                                                android:paddingLeft="10dip"
                                                android:paddingRight="33dip"
                                                android:src="@drawable/tab_new"
--- a/mobile/android/base/resources/layout-large-v11/tabs_panel_toolbar_menu.xml
+++ b/mobile/android/base/resources/layout-large-v11/tabs_panel_toolbar_menu.xml
@@ -19,34 +19,20 @@
                                       android:paddingLeft="48dip"
                                       android:paddingRight="14dip"
                                       android:enabled="false"/>
 
         <LinearLayout android:layout_width="fill_parent"
                       android:layout_height="fill_parent"
                       android:layout_marginRight="28dip">
 
-            <TextView android:id="@+id/title"
-                      android:layout_width="wrap_content"
-                      android:layout_height="fill_parent"
-                      android:layout_weight="1.0"
-                      style="@style/TabRowTextAppearance"
-                      android:gravity="center_vertical"
-                      android:padding="10dip"
-                      android:textSize="16sp"/>
-
-            <ImageButton android:id="@+id/remote_tabs"
-                         android:layout_width="@dimen/browser_toolbar_height"
-                         android:layout_height="@dimen/browser_toolbar_height"
-                         android:gravity="center_vertical"
-                         android:padding="12dip"
-                         android:src="@drawable/remote_tabs_level"
-                         android:contentDescription="@string/remote_tabs"
-                         android:background="@drawable/action_bar_button"
-                         android:visibility="gone"/>
+            <TabWidget android:id="@android:id/tabs"
+                       android:layout_width="0dip"
+                       android:layout_height="fill_parent"
+                       android:layout_weight="1.0"/>
 
             <org.mozilla.gecko.TabsPanelButton android:id="@+id/add_tab"
                                                android:layout_width="85dip"
                                                android:layout_height="@dimen/browser_toolbar_height"
                                                android:gravity="center_vertical"
                                                android:paddingLeft="14dip"
                                                android:paddingRight="43dip"
                                                android:src="@drawable/tab_new"
--- a/mobile/android/base/resources/layout-xlarge-v11/tabs_panel_toolbar_menu.xml
+++ b/mobile/android/base/resources/layout-xlarge-v11/tabs_panel_toolbar_menu.xml
@@ -3,44 +3,32 @@
    - 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/. -->
 
 <merge xmlns:android="http://schemas.android.com/apk/res/android">
 
     <LinearLayout android:layout_width="fill_parent"
                   android:layout_height="fill_parent">
 
+        <TabWidget android:id="@android:id/tabs"
+                   android:layout_width="0dip"
+                   android:layout_height="fill_parent"
+                   android:layout_weight="1.0"/>
+
         <ImageButton android:id="@+id/add_tab"
                      android:layout_width="@dimen/browser_toolbar_height"
                      android:layout_height="@dimen/browser_toolbar_height"
                      android:paddingTop="15dip"
                      android:paddingBottom="15dip"
                      android:paddingLeft="20dip"
                      android:paddingRight="20dip"
                      android:src="@drawable/tab_new"
                      android:contentDescription="@string/new_tab"
                      android:background="@drawable/action_bar_button"/>
 
-        <ImageButton android:id="@+id/remote_tabs"
-                     android:layout_width="@dimen/browser_toolbar_height"
-                     android:layout_height="@dimen/browser_toolbar_height"
-                     android:paddingTop="15dip"
-                     android:paddingBottom="15dip"
-                     android:paddingLeft="20dip"
-                     android:paddingRight="20dip"
-                     android:src="@drawable/remote_tabs_level"
-                     android:contentDescription="@string/remote_tabs"
-                     android:background="@drawable/action_bar_button"
-                     android:visibility="gone"/>
-
-        <TextView android:id="@+id/title"
-                  android:layout_width="wrap_content"
-                  android:layout_height="wrap_content"
-                  android:visibility="gone"/>
-
         <ImageButton android:id="@+id/menu"
                      android:layout_width="@dimen/browser_toolbar_height"
                      android:layout_height="@dimen/browser_toolbar_height"
                      android:paddingTop="15dip"
                      android:paddingBottom="15dip"
                      android:paddingLeft="20dip"
                      android:paddingRight="20dip"
                      android:src="@drawable/tabs_menu"
--- a/mobile/android/base/resources/layout/gecko_app.xml.in
+++ b/mobile/android/base/resources/layout/gecko_app.xml.in
@@ -4,21 +4,21 @@
    - 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/@ANDROID_PACKAGE_NAME@"
                 android:layout_width="fill_parent"
                 android:layout_height="fill_parent">
 
-   <org.mozilla.gecko.TabsPanel android:id="@+id/tabs_panel"
-                                android:layout_width="fill_parent"
-                                android:layout_height="fill_parent"
-                                android:background="@drawable/tabs_tray_bg_repeat"
-                                gecko:sidebar="false"/>
+    <org.mozilla.gecko.TabsPanel android:id="@+id/tabs_panel"
+                                 android:layout_width="fill_parent"
+                                 android:layout_height="fill_parent"
+                                 android:background="@drawable/tabs_tray_bg_repeat"
+                                 gecko:sidebar="false"/>
 
    <view class="org.mozilla.gecko.GeckoApp$MainLayout"
          android:id="@+id/main_layout"
          style="@style/Screen.Transparent">
  
         <!-- BrowserToolbar will be added dynamically -->
 
         <RelativeLayout android:id="@+id/gecko_layout"
rename from mobile/android/base/resources/layout/tabs_panel.xml
rename to mobile/android/base/resources/layout/tabs_panel.xml.in
--- a/mobile/android/base/resources/layout/tabs_panel.xml
+++ b/mobile/android/base/resources/layout/tabs_panel.xml.in
@@ -1,29 +1,53 @@
+#filter substitution
 <?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/. -->
 
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+       xmlns:gecko="http://schemas.android.com/apk/res/@ANDROID_PACKAGE_NAME@">
+
+    <LinearLayout android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+                  android:orientation="vertical">
 
-    <view class="org.mozilla.gecko.TabsPanel$TabsPanelToolbar"
-          android:id="@+id/toolbar"
-          android:layout_width="fill_parent"
-          android:layout_height="@dimen/browser_toolbar_height"/>
+        <view class="org.mozilla.gecko.TabsPanel$TabsPanelToolbar"
+              android:id="@+id/toolbar"
+              android:layout_width="fill_parent"
+              android:layout_height="@dimen/browser_toolbar_height"/>
 
-    <RelativeLayout android:layout_width="fill_parent"
-                    android:layout_height="fill_parent">
+        <RelativeLayout android:layout_width="fill_parent"
+                        android:layout_height="0dip"
+                        android:layout_weight="1.0">
+
+            <view class="org.mozilla.gecko.TabsPanel$TabsListContainer"
+                  android:id="@android:id/tabcontent"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content">
 
-        <view class="org.mozilla.gecko.TabsPanel$TabsListContainer"
-              android:id="@+id/list_container"
-              android:layout_width="fill_parent"
-              android:layout_height="fill_parent"
-              android:orientation="vertical"/>
+                <org.mozilla.gecko.TabsTray android:id="@+id/normal_tabs"
+                                            android:layout_width="fill_parent"
+                                            android:layout_height="fill_parent"
+                                            gecko:tabs="tabs_normal"/>
+
+                <org.mozilla.gecko.TabsTray android:id="@+id/private_tabs"
+                                            android:layout_width="fill_parent"
+                                            android:layout_height="wrap_content"
+                                            gecko:tabs="tabs_private"/>
 
-        <View android:layout_width="fill_parent"
-              android:layout_height="3dp"
-              android:layout_alignParentTop="true"
-              android:background="@drawable/tabs_shadow"/>
+                <org.mozilla.gecko.RemoteTabs android:id="@+id/synced_tabs"
+                                              android:layout_width="fill_parent"
+                                              android:layout_height="wrap_content"/>
+
+            </view>
 
-    </RelativeLayout>
+            <View android:layout_width="fill_parent"
+                  android:layout_height="3dp"
+                  android:layout_alignParentTop="true"
+                  android:background="@drawable/tabs_shadow"/>
+
+       </RelativeLayout>
+
+   </LinearLayout>
 
 </merge>
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/resources/layout/tabs_panel_indicator.xml
@@ -0,0 +1,16 @@
+<?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/. -->
+
+<Gecko.TextView xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="0dip"
+                android:layout_height="fill_parent"
+                android:layout_weight="1.0"
+                android:gravity="center"
+                android:background="@drawable/tabs_panel_indicator"
+                android:padding="10dp"
+                android:singleLine="true"
+                android:ellipsize="marquee"
+                android:textSize="13sp"
+                android:textColor="#FFE5F2FF"/>
--- a/mobile/android/base/resources/layout/tabs_panel_toolbar_menu.xml
+++ b/mobile/android/base/resources/layout/tabs_panel_toolbar_menu.xml
@@ -19,34 +19,20 @@
                                       android:paddingLeft="42dip"
                                       android:paddingRight="12dip"
                                       android:enabled="false"/>
 
         <LinearLayout android:layout_width="fill_parent"
                       android:layout_height="fill_parent"
                       android:layout_marginRight="22dip">
 
-            <TextView android:id="@+id/title"
-                      android:layout_width="wrap_content"
-                      android:layout_height="fill_parent"
-                      android:layout_weight="1.0"
-                      style="@style/TabRowTextAppearance"
-                      android:gravity="center_vertical"
-                      android:padding="10dip"
-                      android:textSize="16sp"/>
-
-            <ImageButton android:id="@+id/remote_tabs"
-                         android:layout_width="@dimen/browser_toolbar_height"
-                         android:layout_height="@dimen/browser_toolbar_height"
-                         android:gravity="center_vertical"
-                         android:padding="12dip"
-                         android:src="@drawable/remote_tabs_level"
-                         android:contentDescription="@string/remote_tabs"
-                         android:background="@drawable/action_bar_button"
-                         android:visibility="gone"/>
+            <TabWidget android:id="@android:id/tabs"
+                       android:layout_width="0dip"
+                       android:layout_height="fill_parent"
+                       android:layout_weight="1.0"/>
 
             <org.mozilla.gecko.TabsPanelButton android:id="@+id/add_tab"
                                                android:layout_width="75dip"
                                                android:layout_height="@dimen/browser_toolbar_height"
                                                android:gravity="center_vertical"
                                                android:paddingLeft="12dip"
                                                android:paddingRight="39dip"
                                                android:src="@drawable/tab_new"
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -137,16 +137,19 @@
   <string name="addons">&addons;</string>
   <string name="downloads">&downloads;</string>
   <string name="apps">&apps;</string>
   <string name="char_encoding">&char_encoding;</string>
   <string name="new_tab">&new_tab;</string>
   <string name="new_private_tab">&new_private_tab;</string>
   <string name="synced_tabs">&synced_tabs;</string>
   <string name="close_all_tabs">&close_all_tabs;</string>
+  <string name="tabs_normal">&tabs_normal;</string>
+  <string name="tabs_private">&tabs_private;</string>
+  <string name="tabs_synced">&tabs_synced;</string>
   <!-- This string only appears in developer builds, which
        is why it is not localizable. -->
   <string name="toggle_profiling">Toggle Profiling</string>
 
   <string name="site_settings_title">&site_settings_title2;</string>
   <string name="site_settings_cancel">&site_settings_cancel;</string>
   <string name="site_settings_clear">&site_settings_clear;</string>
   <string name="site_settings_no_settings">&site_settings_no_settings;</string>