Bug 1262343 - Remove old History panel code. r=sebastian draft
authorChenxia Liu <liuche@mozilla.com>
Wed, 20 Apr 2016 11:41:49 -0700
changeset 354488 9fd38cb4682055bf20ce6c5786ad6cb0a98b820d
parent 354334 b29a652d68e85d25953a2bb371d35114cd8036a0
child 354489 a5648748db28e6f2618bf8b0e447225b2ff371ee
push id16092
push usercliu@mozilla.com
push dateThu, 21 Apr 2016 00:29:20 +0000
reviewerssebastian
bugs1262343
milestone48.0a1
Bug 1262343 - Remove old History panel code. r=sebastian MozReview-Commit-ID: LZX264R3H35
mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
mobile/android/base/java/org/mozilla/gecko/home/HistoryHeaderListCursorAdapter.java
mobile/android/base/java/org/mozilla/gecko/home/HistoryItemAdapter.java
mobile/android/base/java/org/mozilla/gecko/home/HistoryPanel.java
mobile/android/base/java/org/mozilla/gecko/home/HomeConfig.java
mobile/android/base/java/org/mozilla/gecko/home/HomeConfigPrefsBackend.java
mobile/android/base/java/org/mozilla/gecko/preferences/PanelsPreferenceCategory.java
mobile/android/base/moz.build
mobile/android/base/resources/layout-sw600dp-land/home_history_panel.xml
mobile/android/base/resources/layout/home_history_panel.xml
mobile/android/base/resources/layout/home_history_range_item.xml
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -3530,17 +3530,17 @@ public class BrowserApp extends GeckoApp
         if (itemId == R.id.bookmarks_list) {
             final String url = AboutPages.getURLForBuiltinPanelType(PanelType.BOOKMARKS);
             Tabs.getInstance().loadUrl(url);
             Telemetry.startUISession(TelemetryContract.Session.EXPERIMENT, Experiments.BOOKMARKS_HISTORY_MENU);
             return true;
         }
 
         if (itemId == R.id.history_list) {
-            final String url = AboutPages.getURLForBuiltinPanelType(PanelType.HISTORY);
+            final String url = AboutPages.getURLForBuiltinPanelType(PanelType.COMBINED_HISTORY);
             Tabs.getInstance().loadUrl(url);
             Telemetry.startUISession(TelemetryContract.Session.EXPERIMENT, Experiments.BOOKMARKS_HISTORY_MENU);
             return true;
         }
 
         if (itemId == R.id.save_as_pdf) {
             Telemetry.sendUIEvent(TelemetryContract.Event.SAVE, TelemetryContract.Method.MENU, "pdf");
             GeckoAppShell.notifyObservers("SaveAs:PDF", null);
deleted file mode 100644
--- a/mobile/android/base/java/org/mozilla/gecko/home/HistoryHeaderListCursorAdapter.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.home;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.util.SparseArray;
-import android.view.View;
-import android.widget.TextView;
-
-import org.mozilla.gecko.R;
-import org.mozilla.gecko.db.BrowserContract;
-
-/**
- * CursorAdapter for <code>HistoryPanel</code> to partition history items by <code>MostRecentSection</code> range headers.
- */
-public class HistoryHeaderListCursorAdapter extends MultiTypeCursorAdapter implements HistoryPanel.HistoryUrlProvider {
-    private static final int ROW_HEADER = 0;
-    private static final int ROW_STANDARD = 1;
-
-    private static final int[] VIEW_TYPES = new int[] { ROW_STANDARD, ROW_HEADER };
-    private static final int[] LAYOUT_TYPES = new int[] { R.layout.home_item_row, R.layout.home_header_row };
-
-    // Maps headers in the list with their respective sections
-    private final SparseArray<HistoryPanel.MostRecentSection> mMostRecentSections;
-
-    public HistoryHeaderListCursorAdapter(Context context) {
-        super(context, null, VIEW_TYPES, LAYOUT_TYPES);
-
-        // Initialize map of history sections
-        mMostRecentSections = new SparseArray<>();
-    }
-
-    @Override
-    public Object getItem(int position) {
-        final int type = getItemViewType(position);
-
-        // Header items are not in the cursor
-        if (type == ROW_HEADER) {
-            return null;
-        }
-
-        return super.getItem(position - getMostRecentSectionsCountBefore(position));
-    }
-
-    @Override
-    public int getItemViewType(int position) {
-        if (mMostRecentSections.get(position) != null) {
-            return ROW_HEADER;
-        }
-
-        return ROW_STANDARD;
-    }
-
-    @Override
-    public boolean isEnabled(int position) {
-        return (getItemViewType(position) == ROW_STANDARD);
-    }
-
-    @Override
-    public int getCount() {
-        // Add the history section headers to the number of reported results.
-        return super.getCount() + mMostRecentSections.size();
-    }
-
-    @Override
-    public Cursor swapCursor(Cursor cursor) {
-        loadMostRecentSections(cursor);
-        Cursor oldCursor = super.swapCursor(cursor);
-        return oldCursor;
-    }
-
-    @Override
-    public void bindView(View view, Context context, int position) {
-        final int type = getItemViewType(position);
-
-        if (type == ROW_HEADER) {
-            final HistoryPanel.MostRecentSection section = mMostRecentSections.get(position);
-            final TextView row = (TextView) view;
-            row.setText(HistoryPanel.getMostRecentSectionTitle(section));
-        } else {
-            // Account for the most recent section headers
-            position -= getMostRecentSectionsCountBefore(position);
-            final Cursor c = getCursor(position);
-            final TwoLinePageRow row = (TwoLinePageRow) view;
-            row.updateFromCursor(c);
-        }
-    }
-
-    private int getMostRecentSectionsCountBefore(int position) {
-        // Account for the number headers before the given position
-        int sectionsBefore = 0;
-
-        final int historySectionsCount = mMostRecentSections.size();
-        for (int i = 0; i < historySectionsCount; i++) {
-            final int sectionPosition = mMostRecentSections.keyAt(i);
-            if (sectionPosition > position) {
-                break;
-            }
-
-            sectionsBefore++;
-        }
-
-        return sectionsBefore;
-    }
-
-    private void loadMostRecentSections(Cursor c) {
-        // Clear any history sections that may have been loaded before.
-        mMostRecentSections.clear();
-
-        if (c == null || !c.moveToFirst()) {
-            return;
-        }
-
-        HistoryPanel.MostRecentSection section = null;
-
-        do {
-            final int position = c.getPosition();
-            final long time = c.getLong(c.getColumnIndexOrThrow(BrowserContract.History.DATE_LAST_VISITED));
-            final HistoryPanel.MostRecentSection itemSection = HistoryPanel.getMostRecentSectionForTime(time);
-
-            if (section != itemSection) {
-                section = itemSection;
-                mMostRecentSections.append(position + mMostRecentSections.size(), section);
-            }
-
-            // Reached the last section, no need to continue
-            if (section == HistoryPanel.MostRecentSection.OLDER_THAN_SIX_MONTHS) {
-                break;
-            }
-        } while (c.moveToNext());
-    }
-
-    @Override
-    public String getURL(int position) {
-        position -= getMostRecentSectionsCountBefore(position);
-        final Cursor c = getCursor(position);
-        return c.getString(c.getColumnIndexOrThrow(BrowserContract.History.URL));
-    }
-}
deleted file mode 100644
--- a/mobile/android/base/java/org/mozilla/gecko/home/HistoryItemAdapter.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.home;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.support.v4.widget.CursorAdapter;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import org.mozilla.gecko.db.BrowserContract;
-
-/**
- * A Cursor adapter that is used to populate the history list items in split plane mode.
- */
-public class HistoryItemAdapter extends CursorAdapter implements HistoryPanel.HistoryUrlProvider {
-    private final int resource;
-
-    public HistoryItemAdapter(Context context, Cursor c, int resource) {
-        super(context, c, false);
-        this.resource = resource;
-    }
-
-    @Override
-    public View newView(Context context, Cursor cursor, ViewGroup parent) {
-        return LayoutInflater.from(context).inflate(resource, parent, false);
-    }
-
-    @Override
-    public View getView(int position, View convertView, ViewGroup parent) {
-        return super.getView(position, convertView, parent);
-    }
-
-    @Override
-    public void bindView(View view, Context context, Cursor cursor) {
-        final TwoLinePageRow row = (TwoLinePageRow) view;
-        row.updateFromCursor(cursor);
-    }
-
-    @Override
-    public String getURL(int position) {
-        final Cursor cursor = getCursor();
-        if (cursor == null || !cursor.moveToPosition(position)) {
-            throw new IllegalStateException("Couldn't move cursor to position " + position);
-        }
-
-        return cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.History.URL));
-    }
-}
deleted file mode 100644
--- a/mobile/android/base/java/org/mozilla/gecko/home/HistoryPanel.java
+++ /dev/null
@@ -1,518 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.home;
-
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Locale;
-
-import android.support.v4.content.ContextCompat;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import org.mozilla.gecko.EventDispatcher;
-import org.mozilla.gecko.GeckoAppShell;
-import org.mozilla.gecko.GeckoEvent;
-import org.mozilla.gecko.GeckoProfile;
-import org.mozilla.gecko.R;
-import org.mozilla.gecko.Telemetry;
-import org.mozilla.gecko.TelemetryContract;
-import org.mozilla.gecko.db.BrowserContract.Combined;
-import org.mozilla.gecko.db.BrowserDB;
-import org.mozilla.gecko.home.HomeContextMenuInfo.RemoveItemType;
-import org.mozilla.gecko.home.HomePager.OnUrlOpenListener;
-import org.mozilla.gecko.restrictions.Restrictable;
-import org.mozilla.gecko.restrictions.Restrictions;
-import org.mozilla.gecko.util.HardwareUtils;
-
-import android.app.AlertDialog;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.database.Cursor;
-import android.graphics.Typeface;
-import android.os.Bundle;
-import android.support.v4.app.LoaderManager;
-import android.support.v4.content.Loader;
-import android.support.v4.widget.CursorAdapter;
-import android.text.SpannableStringBuilder;
-import android.text.TextPaint;
-import android.text.method.LinkMovementMethod;
-import android.text.style.ClickableSpan;
-import android.text.style.StyleSpan;
-import android.text.style.UnderlineSpan;
-import android.util.Log;
-import android.view.ContextMenu;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewStub;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-/**
- * Fragment that displays recent history in a ListView.
- */
-public class HistoryPanel extends HomeFragment {
-    // Logging tag name
-    private static final String LOGTAG = "GeckoHistoryPanel";
-
-    // For the time sections in history
-    private static final long MS_PER_DAY = 86400000;
-    private static final long MS_PER_WEEK = MS_PER_DAY * 7;
-    private static final List<MostRecentSectionRange> recentSectionTimeOffsetList = new ArrayList<>(MostRecentSection.values().length);
-
-    // Cursor loader ID for history query
-    private static final int LOADER_ID_HISTORY = 0;
-
-    // String placeholders to mark formatting.
-    private final static String FORMAT_S1 = "%1$s";
-    private final static String FORMAT_S2 = "%2$s";
-
-    // Maintain selected range state.
-    // Only accessed from the UI thread.
-    private static MostRecentSection selected;
-
-    // Adapter for the list of recent history entries.
-    private CursorAdapter mAdapter;
-
-    // Adapter for the timeline of history entries.
-    private ArrayAdapter<MostRecentSection> mRangeAdapter;
-
-    // The view shown by the fragment.
-    private HomeListView mList;
-    private HomeListView mRangeList;
-
-    // The button view for clearing browsing history.
-    private View mClearHistoryButton;
-
-    // Reference to the View to display when there are no results.
-    private View mEmptyView;
-
-    // Callbacks used for the search and favicon cursor loaders
-    private CursorLoaderCallbacks mCursorLoaderCallbacks;
-
-    // The time ranges for each section
-    public enum MostRecentSection {
-        TODAY,
-        YESTERDAY,
-        WEEK,
-        THIS_MONTH,
-        MONTH_AGO,
-        TWO_MONTHS_AGO,
-        THREE_MONTHS_AGO,
-        FOUR_MONTHS_AGO,
-        FIVE_MONTHS_AGO,
-        OLDER_THAN_SIX_MONTHS
-    };
-
-    protected interface HistoryUrlProvider {
-        public String getURL(int position);
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        return inflater.inflate(R.layout.home_history_panel, container, false);
-    }
-
-    @Override
-    public void onViewCreated(View view, Bundle savedInstanceState) {
-        super.onViewCreated(view, savedInstanceState);
-
-        mRangeList = (HomeListView) view.findViewById(R.id.range_list);
-        mList = (HomeListView) view.findViewById(R.id.list);
-        mList.setTag(HomePager.LIST_TAG_HISTORY);
-
-        if (mRangeList != null) {
-            mRangeList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
-                @Override
-                public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
-                    final MostRecentSection rangeItem = (MostRecentSection) adapter.getItemAtPosition(position);
-                    if (rangeItem != null) {
-                        // Notify data has changed for both range and item adapter.
-                        // This will update selected rangeItem item background and the tabs list.
-                        // This will also update the selected range along with cursor start and end.
-                        selected = rangeItem;
-                        mRangeAdapter.notifyDataSetChanged();
-                        getLoaderManager().getLoader(LOADER_ID_HISTORY).forceLoad();
-                        mList.smoothScrollToPosition(0);
-                    }
-                }
-            });
-        }
-
-        mList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
-            @Override
-            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-                final String url = ((HistoryUrlProvider) mAdapter).getURL(position);
-
-                Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryContract.Method.LIST_ITEM, "history");
-
-                // This item is a TwoLinePageRow, so we allow switch-to-tab.
-                mUrlOpenListener.onUrlOpen(url, EnumSet.of(OnUrlOpenListener.Flags.ALLOW_SWITCH_TO_TAB));
-            }
-        });
-
-        mList.setContextMenuInfoFactory(new HomeContextMenuInfo.Factory() {
-            @Override
-            public HomeContextMenuInfo makeInfoForCursor(View view, int position, long id, Cursor cursor) {
-                final HomeContextMenuInfo info = new HomeContextMenuInfo(view, position, id);
-                info.url = cursor.getString(cursor.getColumnIndexOrThrow(Combined.URL));
-                info.title = cursor.getString(cursor.getColumnIndexOrThrow(Combined.TITLE));
-                info.historyId = cursor.getInt(cursor.getColumnIndexOrThrow(Combined.HISTORY_ID));
-                info.itemType = RemoveItemType.HISTORY;
-                final int bookmarkIdCol = cursor.getColumnIndexOrThrow(Combined.BOOKMARK_ID);
-                if (cursor.isNull(bookmarkIdCol)) {
-                    // If this is a combined cursor, we may get a history item without a
-                    // bookmark, in which case the bookmarks ID column value will be null.
-                    info.bookmarkId =  -1;
-                } else {
-                    info.bookmarkId = cursor.getInt(bookmarkIdCol);
-                }
-                return info;
-            }
-        });
-        registerForContextMenu(mList);
-
-        mClearHistoryButton = view.findViewById(R.id.clear_history_button);
-        mClearHistoryButton.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                final Context context = getActivity();
-
-                final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
-                dialogBuilder.setMessage(R.string.home_clear_history_confirm);
-
-                dialogBuilder.setNegativeButton(R.string.button_cancel, new AlertDialog.OnClickListener() {
-                    @Override
-                    public void onClick(final DialogInterface dialog, final int which) {
-                        dialog.dismiss();
-                    }
-                });
-
-                dialogBuilder.setPositiveButton(R.string.button_ok, new AlertDialog.OnClickListener() {
-                    @Override
-                    public void onClick(final DialogInterface dialog, final int which) {
-                        dialog.dismiss();
-
-                        // Send message to Java to clear history.
-                        final JSONObject json = new JSONObject();
-                        try {
-                            json.put("history", true);
-                        } catch (JSONException e) {
-                            Log.e(LOGTAG, "JSON error", e);
-                        }
-
-                        GeckoAppShell.notifyObservers("Sanitize:ClearData", json.toString());
-
-                        Telemetry.sendUIEvent(TelemetryContract.Event.SANITIZE, TelemetryContract.Method.BUTTON, "history");
-                    }
-                });
-
-                dialogBuilder.show();
-            }
-        });
-    }
-
-    @Override
-    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
-        super.onCreateContextMenu(menu, view, menuInfo);
-
-        if (!Restrictions.isAllowed(getActivity(), Restrictable.CLEAR_HISTORY)) {
-            menu.findItem(R.id.home_remove).setVisible(false);
-        }
-    }
-
-    @Override
-    public void onDestroyView() {
-        super.onDestroyView();
-
-        // Discard any additional item clicks on the list as the
-        // panel is getting destroyed (bug 1210243).
-        if (mRangeList != null) {
-            mRangeList.setOnItemClickListener(null);
-        }
-        mList.setOnItemClickListener(null);
-
-        mRangeList = null;
-        mList = null;
-        mEmptyView = null;
-        mClearHistoryButton = null;
-    }
-
-    @Override
-    public void onActivityCreated(Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-
-        // Reset selection.
-        selected = mRangeList == null ? MostRecentSection.THIS_MONTH : MostRecentSection.TODAY;
-
-        // Initialize adapter
-        if (mRangeList != null) {
-            mAdapter = new HistoryItemAdapter(getActivity(), null, R.layout.home_item_row);
-            mRangeAdapter = new HistoryRangeAdapter(getActivity(), R.layout.home_history_range_item);
-
-            mRangeList.setAdapter(mRangeAdapter);
-            mList.setAdapter(mAdapter);
-        } else {
-            mAdapter = new HistoryHeaderListCursorAdapter(getActivity());
-            mList.setAdapter(mAdapter);
-        }
-
-        // Create callbacks before the initial loader is started
-        mCursorLoaderCallbacks = new CursorLoaderCallbacks();
-
-        // Update the section string with current time as reference.
-        updateRecentSectionOffset(getActivity());
-        loadIfVisible();
-    }
-
-    @Override
-    protected void loadIfVisible() {
-        // Force reload fragment only in tablets.
-        if (canLoad() && HardwareUtils.isTablet()) {
-            load();
-            return;
-        }
-
-         super.loadIfVisible();
-    }
-
-    @Override
-    protected void load() {
-        getLoaderManager().initLoader(LOADER_ID_HISTORY, null, mCursorLoaderCallbacks);
-    }
-
-    private void updateUiFromCursor(Cursor c) {
-        if (c != null && c.getCount() > 0) {
-            if (Restrictions.isAllowed(getActivity(), Restrictable.CLEAR_HISTORY)) {
-                mClearHistoryButton.setVisibility(View.VISIBLE);
-            }
-            return;
-        }
-
-        // Cursor is empty, so hide the "Clear browsing history" button,
-        // and set the empty view if it hasn't been set already.
-        mClearHistoryButton.setVisibility(View.GONE);
-
-        if (mEmptyView == null) {
-            // Set empty panel view. We delay this so that the empty view won't flash.
-            final ViewStub emptyViewStub = (ViewStub) getView().findViewById(R.id.home_empty_view_stub);
-            mEmptyView = emptyViewStub.inflate();
-
-            final ImageView emptyIcon = (ImageView) mEmptyView.findViewById(R.id.home_empty_image);
-            emptyIcon.setImageResource(R.drawable.icon_most_recent_empty);
-
-            final TextView emptyText = (TextView) mEmptyView.findViewById(R.id.home_empty_text);
-            if (selected == null || mRangeAdapter == null || mRangeList == null) {
-                emptyText.setText(R.string.home_most_recent_empty);
-            } else {
-                emptyText.setText(R.string.home_selected_empty);
-            }
-
-            final TextView emptyHint = (TextView) mEmptyView.findViewById(R.id.home_empty_hint);
-            final String hintText = getResources().getString(R.string.home_most_recent_emptyhint);
-
-            final SpannableStringBuilder hintBuilder = formatHintText(hintText);
-            if (hintBuilder != null) {
-                emptyHint.setText(hintBuilder);
-                emptyHint.setMovementMethod(LinkMovementMethod.getInstance());
-                emptyHint.setVisibility(View.VISIBLE);
-            }
-
-            if (!Restrictions.isAllowed(getActivity(), Restrictable.PRIVATE_BROWSING)) {
-                emptyHint.setVisibility(View.GONE);
-            }
-
-            mList.setEmptyView(mEmptyView);
-        }
-    }
-
-    /**
-     * Make Span that is clickable, and underlined
-     * between the string markers <code>FORMAT_S1</code> and
-     * <code>FORMAT_S2</code>.
-     *
-     * @param text String to format
-     * @return formatted SpannableStringBuilder, or null if there
-     * is not any text to format.
-     */
-    private SpannableStringBuilder formatHintText(String text) {
-        // Set formatting as marked by string placeholders.
-        final int underlineStart = text.indexOf(FORMAT_S1);
-        final int underlineEnd = text.indexOf(FORMAT_S2);
-
-        // Check that there is text to be formatted.
-        if (underlineStart >= underlineEnd) {
-            return null;
-        }
-
-        final SpannableStringBuilder ssb = new SpannableStringBuilder(text);
-
-        // Set clickable text.
-        final ClickableSpan clickableSpan = new ClickableSpan() {
-            @Override
-            public void onClick(View widget) {
-                Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.PANEL, "hint-private-browsing");
-                try {
-                    final JSONObject json = new JSONObject();
-                    json.put("type", "Menu:Open");
-                    EventDispatcher.getInstance().dispatchEvent(json, null);
-                } catch (JSONException e) {
-                    Log.e(LOGTAG, "Error forming JSON for Private Browsing contextual hint", e);
-                }
-            }
-        };
-
-        ssb.setSpan(clickableSpan, 0, text.length(), 0);
-
-        // Remove underlining set by ClickableSpan.
-        final UnderlineSpan noUnderlineSpan = new UnderlineSpan() {
-            @Override
-            public void updateDrawState(TextPaint textPaint) {
-                textPaint.setUnderlineText(false);
-            }
-        };
-
-        ssb.setSpan(noUnderlineSpan, 0, text.length(), 0);
-
-        // Add underlining for "Private Browsing".
-        ssb.setSpan(new UnderlineSpan(), underlineStart, underlineEnd, 0);
-
-        ssb.delete(underlineEnd, underlineEnd + FORMAT_S2.length());
-        ssb.delete(underlineStart, underlineStart + FORMAT_S1.length());
-
-        return ssb;
-    }
-
-    private static void updateRecentSectionOffset(final Context context) {
-        final long now = System.currentTimeMillis();
-        final Calendar cal  = Calendar.getInstance();
-        cal.set(Calendar.HOUR_OF_DAY, 0);
-        cal.set(Calendar.MINUTE, 0);
-        cal.set(Calendar.SECOND, 0);
-        cal.set(Calendar.MILLISECOND, 1);
-
-        // Calculate the start, end time and display text for the MostRecentSection range.
-        recentSectionTimeOffsetList.add(MostRecentSection.TODAY.ordinal(),
-                new MostRecentSectionRange(cal.getTimeInMillis(), now, context.getString(R.string.history_today_section)));
-        recentSectionTimeOffsetList.add(MostRecentSection.YESTERDAY.ordinal(),
-                new MostRecentSectionRange(cal.getTimeInMillis() - MS_PER_DAY, cal.getTimeInMillis(), context.getString(R.string.history_yesterday_section)));
-        recentSectionTimeOffsetList.add(MostRecentSection.WEEK.ordinal(),
-                new MostRecentSectionRange(cal.getTimeInMillis() - MS_PER_WEEK, now, context.getString(R.string.history_week_section)));
-
-        // Update the calendar to start of next month.
-        cal.add(Calendar.MONTH, 1);
-        cal.set(Calendar.DAY_OF_MONTH, cal.getMinimum(Calendar.DAY_OF_MONTH));
-
-        // Iterate over the remaining MostRecentSections, to find the start, end and display text.
-        for (int i = MostRecentSection.THIS_MONTH.ordinal(); i < MostRecentSection.OLDER_THAN_SIX_MONTHS.ordinal(); i++) {
-            final long end = cal.getTimeInMillis();
-            cal.add(Calendar.MONTH, -1);
-            final long start = cal.getTimeInMillis();
-            final String displayName = cal.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault());
-            recentSectionTimeOffsetList.add(i, new MostRecentSectionRange(start, end, displayName));
-        }
-        recentSectionTimeOffsetList.add(MostRecentSection.OLDER_THAN_SIX_MONTHS.ordinal(),
-                new MostRecentSectionRange(0L, cal.getTimeInMillis(), context.getString(R.string.history_older_section)));
-    }
-
-    private static class HistoryCursorLoader extends SimpleCursorLoader {
-        // Max number of history results
-        private static final int HISTORY_LIMIT = 100;
-        private final BrowserDB mDB;
-
-        public HistoryCursorLoader(Context context) {
-            super(context);
-            mDB = GeckoProfile.get(context).getDB();
-        }
-
-        @Override
-        public Cursor loadCursor() {
-            final ContentResolver cr = getContext().getContentResolver();
-            updateRecentSectionOffset(getContext());
-            MostRecentSectionRange mostRecentSectionRange = recentSectionTimeOffsetList.get(selected.ordinal());
-            return mDB.getRecentHistoryBetweenTime(cr, HISTORY_LIMIT, mostRecentSectionRange.start, mostRecentSectionRange.end);
-        }
-    }
-
-    protected static String getMostRecentSectionTitle(MostRecentSection section) {
-        return recentSectionTimeOffsetList.get(section.ordinal()).displayName;
-    }
-
-    protected static MostRecentSection getMostRecentSectionForTime(long time) {
-        for (int i = 0; i < MostRecentSection.OLDER_THAN_SIX_MONTHS.ordinal(); i++) {
-            if (time > recentSectionTimeOffsetList.get(i).start) {
-                return MostRecentSection.values()[i];
-            }
-        }
-
-        return MostRecentSection.OLDER_THAN_SIX_MONTHS;
-    }
-
-    private static class MostRecentSectionRange {
-        private final long start;
-        private final long end;
-        private final String displayName;
-
-        private MostRecentSectionRange(long start, long end, String displayName) {
-            this.start = start;
-            this.end = end;
-            this.displayName = displayName;
-        }
-    }
-
-    private static class HistoryRangeAdapter extends ArrayAdapter<MostRecentSection> {
-        private final Context context;
-        private final int resource;
-
-        public HistoryRangeAdapter(Context context, int resource) {
-            super(context, resource, MostRecentSection.values());
-            this.context = context;
-            this.resource = resource;
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            final View view;
-            if (convertView != null) {
-                view = convertView;
-            } else {
-                final LayoutInflater inflater = LayoutInflater.from(context);
-                view = inflater.inflate(resource, parent, false);
-                view.setTag(view.findViewById(R.id.range_title));
-            }
-            final MostRecentSection current = getItem(position);
-            final TextView textView = (TextView) view.getTag();
-            textView.setText(getMostRecentSectionTitle(current));
-            textView.setTextColor(ContextCompat.getColor(context, current == selected ? R.color.text_and_tabs_tray_grey : R.color.disabled_grey));
-            textView.setCompoundDrawablesWithIntrinsicBounds(0, 0, current == selected ? R.drawable.home_group_collapsed : 0, 0);
-            return view;
-        }
-    }
-
-    private class CursorLoaderCallbacks implements LoaderManager.LoaderCallbacks<Cursor> {
-        @Override
-        public Loader<Cursor> onCreateLoader(int id, Bundle args) {
-            return new HistoryCursorLoader(getActivity());
-        }
-
-        @Override
-        public void onLoadFinished(Loader<Cursor> loader, Cursor c) {
-            mAdapter.swapCursor(c);
-            updateUiFromCursor(c);
-        }
-
-        @Override
-        public void onLoaderReset(Loader<Cursor> loader) {
-            mAdapter.swapCursor(null);
-        }
-    }
-}
--- a/mobile/android/base/java/org/mozilla/gecko/home/HomeConfig.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/HomeConfig.java
@@ -26,29 +26,29 @@ import org.mozilla.gecko.util.ThreadUtil
 import android.content.Context;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
 import android.util.Pair;
 
 public final class HomeConfig {
     public static final String PREF_KEY_BOOKMARKS_PANEL_ENABLED = "bookmarksPanelEnabled";
-    public static final String PREF_KEY_HISTORY_PANEL_ENABLED = "historyPanelEnabled";
+    public static final String PREF_KEY_HISTORY_PANEL_ENABLED = "combinedHistoryPanelEnabled";
 
     /**
      * Used to determine what type of HomeFragment subclass to use when creating
      * a given panel. With the exception of DYNAMIC, all of these types correspond
      * to a default set of built-in panels. The DYNAMIC panel type is used by
      * third-party services to create panels with varying types of content.
      */
     @RobocopTarget
     public static enum PanelType implements Parcelable {
         TOP_SITES("top_sites", TopSitesPanel.class),
         BOOKMARKS("bookmarks", BookmarksPanel.class),
-        HISTORY("history", HistoryPanel.class),
+        HISTORY("history", CombinedHistoryPanel.class),
         COMBINED_HISTORY("combined_history", CombinedHistoryPanel.class),
         REMOTE_TABS("remote_tabs", RemoteTabsPanel.class),
         READING_LIST("reading_list", ReadingListPanel.class),
         RECENT_TABS("recent_tabs", RecentTabsPanel.class),
         DYNAMIC("dynamic", DynamicPanel.class);
 
         private final String mId;
         private final Class<?> mPanelClass;
@@ -1635,18 +1635,18 @@ public final class HomeConfig {
     public static int getTitleResourceIdForBuiltinPanelType(PanelType panelType) {
         switch (panelType) {
         case TOP_SITES:
             return R.string.home_top_sites_title;
 
         case BOOKMARKS:
             return R.string.bookmarks_title;
 
+        case HISTORY:
         case COMBINED_HISTORY:
-        case HISTORY:
             return R.string.home_history_title;
 
         case REMOTE_TABS:
             return R.string.home_remote_tabs_title;
 
         case READING_LIST:
             return R.string.reading_list_title;
 
--- a/mobile/android/base/java/org/mozilla/gecko/home/HomeConfigPrefsBackend.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/HomeConfigPrefsBackend.java
@@ -485,17 +485,17 @@ public class HomeConfigPrefsBackend impl
      * used to control the visibility of the corresponding menu items.
      */
     private void updatePrefsFromConfig(JSONArray panelsArray) {
         final SharedPreferences prefs = GeckoSharedPrefs.forProfile(mContext);
         if (!prefs.contains(HomeConfig.PREF_KEY_BOOKMARKS_PANEL_ENABLED)
                 || !prefs.contains(HomeConfig.PREF_KEY_HISTORY_PANEL_ENABLED)) {
 
             final String bookmarkType = PanelType.BOOKMARKS.toString();
-            final String historyType = PanelType.HISTORY.toString();
+            final String historyType = PanelType.COMBINED_HISTORY.toString();
             try {
                 for (int i = 0; i < panelsArray.length(); i++) {
                     final JSONObject panelObj = panelsArray.getJSONObject(i);
                     final String panelType = panelObj.optString(PanelConfig.JSON_KEY_TYPE, null);
                     if (panelType == null) {
                         break;
                     }
                     final boolean isDisabled = panelObj.optBoolean(PanelConfig.JSON_KEY_DISABLED, false);
--- a/mobile/android/base/java/org/mozilla/gecko/preferences/PanelsPreferenceCategory.java
+++ b/mobile/android/base/java/org/mozilla/gecko/preferences/PanelsPreferenceCategory.java
@@ -231,17 +231,17 @@ public class PanelsPreferenceCategory ex
         } else {
             Telemetry.sendUIEvent(TelemetryContract.Event.PANEL_SHOW, Method.DIALOG, id);
         }
 
         if (HomeConfig.getIdForBuiltinPanelType(HomeConfig.PanelType.BOOKMARKS).equals(id)) {
             GeckoSharedPrefs.forProfile(getContext()).edit().putBoolean(HomeConfig.PREF_KEY_BOOKMARKS_PANEL_ENABLED, !toHide).apply();
         }
 
-        if (HomeConfig.getIdForBuiltinPanelType(HomeConfig.PanelType.HISTORY).equals(id)) {
+        if (HomeConfig.getIdForBuiltinPanelType(HomeConfig.PanelType.COMBINED_HISTORY).equals(id)) {
             GeckoSharedPrefs.forProfile(getContext()).edit().putBoolean(HomeConfig.PREF_KEY_HISTORY_PANEL_ENABLED, !toHide).apply();
         }
 
         pref.setHidden(toHide);
         setDefaultFromConfig();
     }
 
     /**
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -384,19 +384,16 @@ gbjar.sources += ['java/org/mozilla/geck
     'home/BookmarksPanel.java',
     'home/BrowserSearch.java',
     'home/CombinedHistoryAdapter.java',
     'home/CombinedHistoryItem.java',
     'home/CombinedHistoryPanel.java',
     'home/CombinedHistoryRecyclerView.java',
     'home/DynamicPanel.java',
     'home/FramePanelLayout.java',
-    'home/HistoryHeaderListCursorAdapter.java',
-    'home/HistoryItemAdapter.java',
-    'home/HistoryPanel.java',
     'home/HistorySectionsHelper.java',
     'home/HomeAdapter.java',
     'home/HomeBanner.java',
     'home/HomeConfig.java',
     'home/HomeConfigLoader.java',
     'home/HomeConfigPrefsBackend.java',
     'home/HomeContextMenuInfo.java',
     'home/HomeExpandableListView.java',
deleted file mode 100644
--- a/mobile/android/base/resources/layout-sw600dp-land/home_history_panel.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?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/. -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent"
-              android:orientation="vertical">
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1"
-        android:orientation="horizontal">
-
-        <org.mozilla.gecko.home.HomeListView
-            android:id="@+id/range_list"
-            style="@style/Widget.HistoryListView"
-            android:layout_width="0dp"
-            android:layout_height="match_parent"
-            android:layout_weight="@dimen/split_plane_left_pane_weight"/>
-
-        <View
-            android:layout_width="1dp"
-            android:layout_height="match_parent"
-            android:background="@color/toolbar_divider_grey"/>
-
-        <ViewStub android:id="@id/home_empty_view_stub"
-                  android:layout="@layout/home_empty_panel"
-                  android:layout_height="match_parent"
-                  android:layout_width="0dp"
-                  android:layout_weight="@dimen/split_plane_right_pane_weight"/>
-
-        <org.mozilla.gecko.home.HomeListView
-            android:id="@+id/list"
-            style="@style/Widget.HistoryListView"
-            android:layout_width="0dp"
-            android:layout_height="match_parent"
-            android:layout_weight="@dimen/split_plane_right_pane_weight"/>
-
-    </LinearLayout>
-
-    <include layout="@layout/home_history_clear_button"/>
-
-</LinearLayout>
deleted file mode 100644
--- a/mobile/android/base/resources/layout/home_history_panel.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?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/. -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent"
-              android:orientation="vertical">
-
-    <include layout="@layout/home_list"/>
-
-    <include layout="@layout/home_history_clear_button"/>
-
-</LinearLayout>
deleted file mode 100644
--- a/mobile/android/base/resources/layout/home_history_range_item.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?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/. -->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-             android:background="@color/about_page_header_grey"
-             android:layout_width="match_parent"
-             android:layout_height="@dimen/home_header_item_height">
-
-    <TextView android:id="@+id/range_title"
-              style="@style/Widget.TwoLinePageRow.Title"
-              android:paddingLeft="15dp"
-              android:paddingRight="15dp"
-              android:layout_gravity="center_vertical"
-              android:layout_width="match_parent"
-              android:layout_height="wrap_content"/>
-</FrameLayout>