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 122294 296cc3ea6e9e4cec791933e481aef825760a6430
parent 122293 93e12399bae42c6a3aa28637e2fe438755feb89a
child 122295 7998f3adb4c5ba142c65e0759b7779b9ed05c3de
push idunknown
push userunknown
push dateunknown
reviewersmfinkle
bugs817706
milestone20.0a1
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>