Merge "Fix logging successful search events" into ub-contactsdialer-i-dev
diff --git a/src/com/android/contacts/ContactsDrawerActivity.java b/src/com/android/contacts/ContactsDrawerActivity.java
deleted file mode 100644
index ad4c2ac..0000000
--- a/src/com/android/contacts/ContactsDrawerActivity.java
+++ /dev/null
@@ -1,720 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts;
-
-import android.accounts.Account;
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.graphics.Color;
-import android.graphics.PorterDuff;
-import android.os.Bundle;
-import android.os.Handler;
-import android.provider.ContactsContract.Intents;
-import android.support.annotation.LayoutRes;
-import android.support.design.widget.NavigationView;
-import android.support.v4.view.GravityCompat;
-import android.support.v4.view.MenuItemCompat;
-import android.support.v4.widget.DrawerLayout;
-import android.support.v7.app.ActionBarDrawerToggle;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.SubMenu;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.android.contacts.activities.ActionBarAdapter;
-import com.android.contacts.compat.CompatUtils;
-import com.android.contacts.editor.ContactEditorFragment;
-import com.android.contacts.editor.SelectAccountDialogFragment;
-import com.android.contacts.group.GroupListItem;
-import com.android.contacts.group.GroupMembersFragment;
-import com.android.contacts.group.GroupMetaData;
-import com.android.contacts.group.GroupNameEditDialogFragment;
-import com.android.contacts.group.GroupUtil;
-import com.android.contacts.group.GroupsFragment;
-import com.android.contacts.group.GroupsFragment.GroupsListener;
-import com.android.contacts.interactions.AccountFiltersFragment;
-import com.android.contacts.interactions.AccountFiltersFragment.AccountFiltersListener;
-import com.android.contacts.list.AccountFilterActivity;
-import com.android.contacts.list.ContactListFilter;
-import com.android.contacts.list.ContactListFilterController;
-import com.android.contacts.list.DefaultContactBrowseListFragment;
-import com.android.contacts.list.MultiSelectContactsListFragment;
-import com.android.contacts.model.AccountTypeManager;
-import com.android.contacts.model.account.AccountDisplayInfo;
-import com.android.contacts.model.account.AccountDisplayInfoFactory;
-import com.android.contacts.model.account.AccountInfo;
-import com.android.contacts.model.account.AccountWithDataSet;
-import com.android.contacts.preference.ContactsPreferenceActivity;
-import com.android.contacts.util.AccountFilterUtil;
-import com.android.contacts.util.ImplicitIntentsUtil;
-import com.android.contacts.util.MaterialColorMapUtils;
-import com.android.contacts.util.SharedPreferenceUtil;
-import com.android.contacts.util.ViewUtil;
-import com.android.contactsbind.HelpUtils;
-import com.android.contactsbind.ObjectFactory;
-import com.google.common.util.concurrent.Futures;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * A common superclass for Contacts activities with a navigation drawer.
- */
-public abstract class ContactsDrawerActivity extends AppCompatContactsActivity implements
-        AccountFiltersListener,
-        GroupsListener,
-        NavigationView.OnNavigationItemSelectedListener,
-        SelectAccountDialogFragment.Listener {
-
-    /** Possible views of Contacts app. */
-    public enum ContactsView {
-        NONE,
-        ALL_CONTACTS,
-        ASSISTANT,
-        GROUP_VIEW,
-        ACCOUNT_VIEW,
-    }
-
-    protected static String TAG = "ContactsDrawerActivity";
-
-    private static final String TAG_GROUPS = "groups";
-    private static final String TAG_FILTERS = "filters";
-    private static final String TAG_SELECT_ACCOUNT_DIALOG = "selectAccountDialog";
-    private static final String TAG_GROUP_NAME_EDIT_DIALOG = "groupNameEditDialog";
-
-    private static final String KEY_NEW_GROUP_ACCOUNT = "newGroupAccount";
-    private static final String KEY_CONTACTS_VIEW = "contactsView";
-
-    private static final long DRAWER_CLOSE_DELAY = 300L;
-
-    protected ContactsView mCurrentView;
-
-    private class ContactsActionBarDrawerToggle extends ActionBarDrawerToggle {
-        private boolean mMenuClickedBefore = SharedPreferenceUtil.getHamburgerMenuClickedBefore(
-                ContactsDrawerActivity.this);
-
-        public ContactsActionBarDrawerToggle(AppCompatActivity activity, DrawerLayout drawerLayout,
-                Toolbar toolbar, int openDrawerContentDescRes, int closeDrawerContentDescRes) {
-            super(activity, drawerLayout, toolbar, openDrawerContentDescRes,
-                    closeDrawerContentDescRes);
-        }
-
-        @Override
-        public void onDrawerOpened(View drawerView) {
-            super.onDrawerOpened(drawerView);
-            if (!mMenuClickedBefore) {
-                SharedPreferenceUtil.setHamburgerMenuClickedBefore(ContactsDrawerActivity.this);
-                mMenuClickedBefore = true;
-            }
-            invalidateOptionsMenu();
-            // Stop search and selection mode like Gmail and Keep. Otherwise, if user switches to
-            // another fragment in navigation drawer, the current search/selection mode will be
-            // overlaid by the action bar of the newly-created fragment.
-            stopSearchAndSelection();
-            updateStatusBarBackground();
-        }
-
-        private void stopSearchAndSelection() {
-            final MultiSelectContactsListFragment listFragment;
-            if (isAllContactsView() || isAccountView()) {
-                listFragment = getAllFragment();
-            } else if (isGroupView()) {
-                listFragment = getGroupFragment();
-            } else {
-                listFragment = null;
-            }
-            if (listFragment == null) {
-                return;
-            }
-            final ActionBarAdapter actionBarAdapter = listFragment.getActionBarAdapter();
-            if (actionBarAdapter == null) {
-                return;
-            }
-            if (actionBarAdapter.isSearchMode()) {
-                actionBarAdapter.setSearchMode(false);
-            } else if (actionBarAdapter.isSelectionMode()) {
-                actionBarAdapter.setSelectionMode(false);
-            }
-        }
-
-        @Override
-        public void onDrawerClosed(View view) {
-            super.onDrawerClosed(view);
-            invalidateOptionsMenu();
-        }
-
-        @Override
-        public void onDrawerStateChanged(int newState) {
-            super.onDrawerStateChanged(newState);
-            // Set transparent status bar when drawer starts to move.
-            if (newState != DrawerLayout.STATE_IDLE) {
-                updateStatusBarBackground();
-            }
-            initializeAssistantNewBadge();
-        }
-    }
-
-    protected ContactListFilterController mContactListFilterController;
-    protected DrawerLayout mDrawer;
-    protected ContactsActionBarDrawerToggle mToggle;
-    protected Toolbar mToolbar;
-    protected NavigationView mNavigationView;
-    protected GroupsFragment mGroupsFragment;
-    protected AccountFiltersFragment mAccountFiltersFragment;
-
-    // The account the new group will be created under.
-    private AccountWithDataSet mNewGroupAccount;
-
-    // Recycle badge if possible
-    private TextView mAssistantNewBadge;
-
-    // Checkable menu item lookup maps. Every map declared here should be added to
-    // clearCheckedMenus() so that they can be cleared.
-    // TODO find a better way to handle selected menu item state, when switching to fragments.
-    protected Map<Long, MenuItem> mGroupMenuMap = new HashMap<>();
-    protected Map<ContactListFilter, MenuItem> mFilterMenuMap = new HashMap<>();
-    protected Map<Integer, MenuItem> mIdMenuMap = new HashMap<>();
-
-    @Override
-    protected void onCreate(Bundle savedState) {
-        super.onCreate(savedState);
-
-        mContactListFilterController = ContactListFilterController.getInstance(this);
-        mContactListFilterController.checkFilterValidity(false);
-
-        super.setContentView(R.layout.contacts_drawer_activity);
-
-        // Set up the action bar.
-        mToolbar = getView(R.id.toolbar);
-        setSupportActionBar(mToolbar);
-
-        // Add shadow under toolbar.
-        ViewUtil.addRectangularOutlineProvider(findViewById(R.id.toolbar_parent), getResources());
-
-        // Set up hamburger button.
-        mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
-        mToggle = new ContactsActionBarDrawerToggle(this, mDrawer, mToolbar,
-                R.string.navigation_drawer_open, R.string.navigation_drawer_close);
-
-        mDrawer.setDrawerListener(mToggle);
-        // Set fallback handler for when drawer is disabled.
-        mToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                onBackPressed();
-            }
-        });
-
-        // Set up navigation mode.
-        if (savedState != null) {
-            mCurrentView = ContactsView.values()[savedState.getInt(KEY_CONTACTS_VIEW)];
-        } else {
-            mCurrentView = ContactsView.ALL_CONTACTS;
-        }
-
-        // Set up hamburger menu items.
-        mNavigationView = (NavigationView) findViewById(R.id.nav_view);
-        mNavigationView.setNavigationItemSelectedListener(this);
-        setUpMenu();
-
-        initializeAssistantNewBadge();
-        loadGroupsAndFilters();
-
-        if (savedState != null && savedState.containsKey(KEY_NEW_GROUP_ACCOUNT)) {
-            mNewGroupAccount = AccountWithDataSet.unstringify(
-                    savedState.getString(KEY_NEW_GROUP_ACCOUNT));
-        }
-    }
-
-    private void initializeAssistantNewBadge() {
-        if (mNavigationView == null) {
-            return;
-        }
-        final MenuItem assistantMenu = mNavigationView.getMenu().findItem(R.id.nav_assistant);
-        if (assistantMenu == null) {
-            return;
-        }
-        final LinearLayout newBadgeFrame =
-                (LinearLayout) MenuItemCompat.getActionView(assistantMenu);
-        final boolean showWelcomeBadge = !SharedPreferenceUtil.isWelcomeCardDismissed(this);
-        if (showWelcomeBadge && newBadgeFrame.getChildCount() == 0) {
-            if (mAssistantNewBadge == null) {
-                mAssistantNewBadge = (TextView) LayoutInflater.from(this)
-                        .inflate(R.layout.assistant_new_badge, null);
-            }
-            newBadgeFrame.setGravity(Gravity.CENTER_VERTICAL);
-            newBadgeFrame.addView(mAssistantNewBadge);
-        } else if (!showWelcomeBadge && newBadgeFrame.getChildCount() > 0) {
-            newBadgeFrame.removeAllViews();
-        }
-    }
-
-    public void setDrawerLockMode(boolean enabled) {
-        // Prevent drawer from being opened by sliding from the start of screen.
-        mDrawer.setDrawerLockMode(enabled ? DrawerLayout.LOCK_MODE_UNLOCKED
-                : DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
-
-        // Order of these statements matter.
-        // Display back button and disable drawer indicator.
-        if (enabled) {
-            getSupportActionBar().setDisplayHomeAsUpEnabled(false);
-            mToggle.setDrawerIndicatorEnabled(true);
-        } else {
-            mToggle.setDrawerIndicatorEnabled(false);
-            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
-        }
-    }
-
-    private void setUpMenu() {
-        final Menu menu = mNavigationView.getMenu();
-
-        if (ObjectFactory.getAssistantFragment() == null) {
-            menu.removeItem(R.id.nav_assistant);
-        } else {
-            final int id = R.id.nav_assistant;
-            final MenuItem assistantMenu = menu.findItem(id);
-            mIdMenuMap.put(id, assistantMenu);
-            if (isAssistantView()) {
-                updateMenuSelection(assistantMenu);
-            }
-        }
-
-        if (!HelpUtils.isHelpAndFeedbackAvailable()) {
-            menu.removeItem(R.id.nav_help);
-        }
-
-        final MenuItem allContactsMenu = menu.findItem(R.id.nav_all_contacts);
-        mIdMenuMap.put(R.id.nav_all_contacts, allContactsMenu);
-        if (isAllContactsView()) {
-            updateMenuSelection(allContactsMenu);
-        }
-    }
-
-    public Toolbar getToolbar() {
-        return mToolbar;
-    }
-
-    @Override
-    protected void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        if (mNewGroupAccount != null) {
-            outState.putString(KEY_NEW_GROUP_ACCOUNT, mNewGroupAccount.stringify());
-        }
-        outState.putInt(KEY_CONTACTS_VIEW, mCurrentView.ordinal());
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-        if (mDrawer.isDrawerOpen(GravityCompat.START)) {
-            updateStatusBarBackground();
-        }
-    }
-
-    public void updateStatusBarBackground() {
-        updateStatusBarBackground(/* color */ -1);
-    }
-
-    public void updateStatusBarBackground(int color) {
-        if (!CompatUtils.isLollipopCompatible()) return;
-        if (color == -1) {
-            mDrawer.setStatusBarBackgroundColor(MaterialColorMapUtils.getStatusBarColor(this));
-        } else {
-            mDrawer.setStatusBarBackgroundColor(color);
-        }
-        mDrawer.invalidate();
-        getWindow().setStatusBarColor(Color.TRANSPARENT);
-    }
-
-    @Override
-    protected void onPostCreate(Bundle savedInstanceState) {
-        super.onPostCreate(savedInstanceState);
-        mToggle.syncState();
-    }
-
-    @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        mToggle.onConfigurationChanged(newConfig);
-    }
-
-    // Set up fragment manager to load groups and filters.
-    protected void loadGroupsAndFilters() {
-        final FragmentManager fragmentManager = getFragmentManager();
-        final FragmentTransaction transaction = fragmentManager.beginTransaction();
-        addGroupsAndFiltersFragments(transaction);
-        transaction.commitAllowingStateLoss();
-        fragmentManager.executePendingTransactions();
-    }
-
-    @Override
-    public void setContentView(@LayoutRes int layoutResID) {
-        final ViewGroup parent = (ViewGroup) findViewById(R.id.content_frame);
-        if (parent != null) {
-            parent.removeAllViews();
-        }
-        LayoutInflater.from(this).inflate(layoutResID, parent);
-    }
-
-    protected void addGroupsAndFiltersFragments(FragmentTransaction transaction) {
-        final FragmentManager fragmentManager = getFragmentManager();
-        mGroupsFragment = (GroupsFragment) fragmentManager.findFragmentByTag(TAG_GROUPS);
-        if (mGroupsFragment == null) {
-            mGroupsFragment = new GroupsFragment();
-            transaction.add(mGroupsFragment, TAG_GROUPS);
-        }
-        mGroupsFragment.setListener(this);
-
-        mAccountFiltersFragment = (AccountFiltersFragment)
-                fragmentManager.findFragmentByTag(TAG_FILTERS);
-        if (mAccountFiltersFragment == null) {
-            mAccountFiltersFragment = new AccountFiltersFragment();
-            transaction.add(mAccountFiltersFragment, TAG_FILTERS);
-        }
-        mAccountFiltersFragment.setListener(this);
-    }
-
-    @Override
-    public void onGroupsLoaded(List<GroupListItem> groupListItems,
-            boolean areGroupWritableAccountsAvailable) {
-        final Menu menu = mNavigationView.getMenu();
-        final MenuItem groupsMenuItem = menu.findItem(R.id.nav_groups);
-        final SubMenu subMenu = groupsMenuItem.getSubMenu();
-        subMenu.removeGroup(R.id.nav_groups_items);
-        mGroupMenuMap = new HashMap<>();
-
-        final GroupMetaData groupMetaData = getGroupMetaData();
-
-        if (groupListItems != null) {
-            // Add each group
-            for (final GroupListItem groupListItem : groupListItems) {
-                if (GroupUtil.isEmptyFFCGroup(groupListItem)) {
-                    continue;
-                }
-                final String title = groupListItem.getTitle();
-                final MenuItem menuItem =
-                        subMenu.add(R.id.nav_groups_items, Menu.NONE, Menu.NONE, title);
-                mGroupMenuMap.put(groupListItem.getGroupId(), menuItem);
-                if (isGroupView() && groupMetaData != null
-                        && groupMetaData.groupId == groupListItem.getGroupId()) {
-                    updateMenuSelection(menuItem);
-                }
-                menuItem.setIcon(R.drawable.quantum_ic_label_vd_theme_24);
-                menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
-                    @Override
-                    public boolean onMenuItemClick(MenuItem item) {
-                        onGroupMenuItemClicked(groupListItem.getGroupId(),
-                                groupListItem.getTitle());
-                        updateMenuSelection(menuItem);
-                        mDrawer.closeDrawer(GravityCompat.START);
-                        return true;
-                    }
-                });
-
-                updateMenuContentDescription(menuItem,
-                        getString(R.string.group_edit_field_hint_text));
-            }
-        }
-
-        // Don't show "Create new..." menu if there's no group-writable accounts available.
-        if (!areGroupWritableAccountsAvailable) {
-            return;
-        }
-
-        // Create a menu item in the sub menu to add new groups
-        final MenuItem menuItem = subMenu.add(R.id.nav_groups_items, Menu.NONE,
-                Menu.NONE, getString(R.string.menu_new_group_action_bar));
-        menuItem.setIcon(R.drawable.quantum_ic_add_vd_theme_24);
-        menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
-            @Override
-            public boolean onMenuItemClick(MenuItem item) {
-                onCreateGroupMenuItemClicked();
-                mDrawer.closeDrawer(GravityCompat.START);
-                return true;
-            }
-        });
-
-        if (isGroupView() && groupMetaData != null) {
-            updateGroupMenu(groupMetaData);
-        }
-    }
-
-    public void updateGroupMenu(GroupMetaData groupMetaData) {
-        clearCheckedMenus();
-        if (groupMetaData != null && mGroupMenuMap != null
-                && mGroupMenuMap.get(groupMetaData.groupId) != null) {
-            setMenuChecked(mGroupMenuMap.get(groupMetaData.groupId), true);
-        }
-    }
-
-    protected GroupMetaData getGroupMetaData() {
-        return null;
-    }
-
-    public boolean isGroupView() {
-        return mCurrentView == ContactsView.GROUP_VIEW;
-    }
-
-    protected boolean isAssistantView() {
-        return mCurrentView == ContactsView.ASSISTANT;
-    }
-
-    protected boolean isAllContactsView() {
-        return mCurrentView == ContactsView.ALL_CONTACTS;
-    }
-
-    protected boolean isAccountView() {
-        return mCurrentView == ContactsView.ACCOUNT_VIEW;
-    }
-
-    public boolean isInSecondLevel() {
-        return isGroupView() || isAssistantView();
-    }
-
-    protected abstract void onGroupMenuItemClicked(long groupId, String title);
-
-    protected void onCreateGroupMenuItemClicked() {
-        // Select the account to create the group
-        final Bundle extras = getIntent().getExtras();
-        final Account account = extras == null ? null :
-                (Account) extras.getParcelable(Intents.Insert.EXTRA_ACCOUNT);
-        if (account == null) {
-            selectAccountForNewGroup();
-        } else {
-            final String dataSet = extras == null
-                    ? null : extras.getString(Intents.Insert.EXTRA_DATA_SET);
-            final AccountWithDataSet accountWithDataSet = new AccountWithDataSet(
-                    account.name, account.type, dataSet);
-            onAccountChosen(accountWithDataSet, /* extraArgs */ null);
-        }
-    }
-
-    @Override
-    public void onFiltersLoaded(List<ContactListFilter> accountFilterItems) {
-        final AccountDisplayInfoFactory accountDisplayFactory = AccountDisplayInfoFactory.
-                fromListFilters(this, accountFilterItems);
-
-        final Menu menu = mNavigationView.getMenu();
-        final MenuItem filtersMenuItem = menu.findItem(R.id.nav_filters);
-        final SubMenu subMenu = filtersMenuItem.getSubMenu();
-        subMenu.removeGroup(R.id.nav_filters_items);
-        mFilterMenuMap = new HashMap<>();
-
-        if (accountFilterItems == null || accountFilterItems.size() < 2) {
-            return;
-        }
-
-        for (int i = 0; i < accountFilterItems.size(); i++) {
-            final ContactListFilter filter = accountFilterItems.get(i);
-            final AccountDisplayInfo displayableAccount =
-                    accountDisplayFactory.getAccountDisplayInfoFor(filter);
-            final CharSequence menuName = displayableAccount.getNameLabel();
-            final MenuItem menuItem = subMenu.add(R.id.nav_filters_items, Menu.NONE,
-                    Menu.NONE, menuName);
-            if (isAccountView() && filter == mContactListFilterController.getFilter()) {
-                updateMenuSelection(menuItem);
-            }
-            mFilterMenuMap.put(filter, menuItem);
-            final Intent intent = new Intent();
-            intent.putExtra(AccountFilterActivity.EXTRA_CONTACT_LIST_FILTER, filter);
-            menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
-                @Override
-                public boolean onMenuItemClick(MenuItem item) {
-                    onFilterMenuItemClicked(intent);
-                    updateMenuSelection(menuItem);
-                    mDrawer.closeDrawer(GravityCompat.START);
-                    return true;
-                }
-            });
-            if (displayableAccount.getIcon() != null) {
-                menuItem.setIcon(displayableAccount.getIcon());
-                // Get rid of the default menu item overlay and show original account icons.
-                menuItem.getIcon().setColorFilter(Color.TRANSPARENT, PorterDuff.Mode.SRC_ATOP);
-            }
-
-            updateMenuContentDescription(menuItem, displayableAccount.getTypeLabel());
-        }
-
-        if (isAccountView()) {
-            updateFilterMenu(mContactListFilterController.getFilter());
-        }
-    }
-
-    private void updateMenuContentDescription(MenuItem menuItem, CharSequence contentDescription) {
-        // Create a dummy action view to attach extra hidden content description to the menuItem
-        // for Talkback. We want Talkback to read out the account type but not have it be part
-        // of the menuItem title.
-        final LinearLayout view = (LinearLayout) LayoutInflater.from(this)
-                .inflate(R.layout.menu_item_action_view, null);
-        view.setContentDescription(contentDescription);
-        view.setVisibility(View.VISIBLE);
-        menuItem.setActionView(view);
-    }
-
-    public void updateFilterMenu(ContactListFilter filter) {
-        clearCheckedMenus();
-        if (filter != null && filter.isContactsFilterType()) {
-            if (mIdMenuMap != null && mIdMenuMap.get(R.id.nav_all_contacts) != null) {
-                setMenuChecked(mIdMenuMap.get(R.id.nav_all_contacts), true);
-            }
-        } else {
-            if (mFilterMenuMap != null && mFilterMenuMap.get(filter) != null) {
-                setMenuChecked(mFilterMenuMap.get(filter), true);
-            }
-        }
-    }
-
-    protected void onFilterMenuItemClicked(Intent intent) {
-        AccountFilterUtil.handleAccountFilterResult(mContactListFilterController,
-                AppCompatActivity.RESULT_OK, intent);
-    }
-
-    @Override
-    public boolean onNavigationItemSelected(final MenuItem item) {
-        final int id = item.getItemId();
-
-        if (id == R.id.nav_settings) {
-            new Handler().postDelayed(new Runnable() {
-                @Override
-                public void run() {
-                    startActivity(createPreferenceIntent());
-                }
-            }, DRAWER_CLOSE_DELAY);
-        } else if (id == R.id.nav_help) {
-            HelpUtils.launchHelpAndFeedbackForMainScreen(ContactsDrawerActivity.this);
-        } else if (id == R.id.nav_all_contacts) {
-            switchToAllContacts();
-        } else if (id == R.id.nav_assistant) {
-            if (!isAssistantView()) {
-                launchAssistant();
-                updateMenuSelection(item);
-            }
-        } else if (item.getIntent() != null) {
-            ImplicitIntentsUtil.startActivityInApp(ContactsDrawerActivity.this,
-                    item.getIntent());
-        } else {
-            Log.w(TAG, "Unhandled navigation view item selection");
-        }
-
-        mDrawer.closeDrawer(GravityCompat.START);
-        return true;
-    }
-
-    private Intent createPreferenceIntent() {
-        final Intent intent = new Intent(this, ContactsPreferenceActivity.class);
-        intent.putExtra(ContactsPreferenceActivity.EXTRA_NEW_LOCAL_PROFILE,
-                ContactEditorFragment.INTENT_EXTRA_NEW_LOCAL_PROFILE);
-        return intent;
-    }
-
-    public void switchToAllContacts() {
-        resetFilter();
-
-        final Menu menu = mNavigationView.getMenu();
-        final MenuItem allContacts = menu.findItem(R.id.nav_all_contacts);
-        updateMenuSelection(allContacts);
-
-        setTitle(getString(R.string.contactsList));
-    }
-
-    private void resetFilter() {
-        final Intent intent = new Intent();
-        final ContactListFilter filter = AccountFilterUtil.createContactsFilter(this);
-        intent.putExtra(AccountFilterActivity.EXTRA_CONTACT_LIST_FILTER, filter);
-        AccountFilterUtil.handleAccountFilterResult(
-                mContactListFilterController, AppCompatActivity.RESULT_OK, intent);
-    }
-
-    protected abstract void launchAssistant();
-
-    protected abstract DefaultContactBrowseListFragment getAllFragment();
-
-    protected abstract GroupMembersFragment getGroupFragment();
-
-    public abstract void showFabWithAnimation(boolean showFab);
-
-    private void clearCheckedMenus() {
-        clearCheckedMenu(mFilterMenuMap);
-        clearCheckedMenu(mGroupMenuMap);
-        clearCheckedMenu(mIdMenuMap);
-    }
-
-    private void clearCheckedMenu(Map<?, MenuItem> map) {
-        final Iterator it = map.entrySet().iterator();
-        while (it.hasNext()) {
-            Entry pair = (Entry) it.next();
-            setMenuChecked(map.get(pair.getKey()), false);
-        }
-    }
-
-    private void setMenuChecked(MenuItem menuItem, boolean checked) {
-        menuItem.setCheckable(checked);
-        menuItem.setChecked(checked);
-    }
-
-    private void selectAccountForNewGroup() {
-        // This should never block because the GroupsFragment loads the accounts and the
-        // "Create Label" item only exists when that loading finishes
-        final List<AccountInfo> accounts = Futures.getUnchecked(AccountTypeManager.getInstance(this)
-                .filterAccountsAsync(AccountTypeManager.AccountFilter.GROUPS_WRITABLE));
-        if (accounts.isEmpty()) {
-            // We shouldn't present the add group button if there are no writable accounts
-            // but check it since it's possible we are started with an Intent.
-            Toast.makeText(this, R.string.groupCreateFailedToast, Toast.LENGTH_SHORT).show();
-            return;
-        }
-        // If there is a single writable account, use it w/o showing a dialog.
-        if (accounts.size() == 1) {
-            onAccountChosen(accounts.get(0).getAccount(), /* extraArgs */ null);
-            return;
-        }
-        SelectAccountDialogFragment.show(getFragmentManager(), R.string.dialog_new_group_account,
-                AccountTypeManager.AccountFilter.GROUPS_WRITABLE, /* extraArgs */ null,
-                TAG_SELECT_ACCOUNT_DIALOG);
-    }
-
-    @Override
-    public void onAccountChosen(AccountWithDataSet account, Bundle extraArgs) {
-        mNewGroupAccount = account;
-        GroupNameEditDialogFragment.newInstanceForCreation(
-                mNewGroupAccount, GroupUtil.ACTION_CREATE_GROUP)
-                .show(getFragmentManager(), TAG_GROUP_NAME_EDIT_DIALOG);
-    }
-
-    @Override
-    public void onAccountSelectorCancelled() {
-    }
-
-    private void updateMenuSelection(MenuItem menuItem) {
-        clearCheckedMenus();
-        setMenuChecked(menuItem, true);
-    }
-}
diff --git a/src/com/android/contacts/activities/ActionBarAdapter.java b/src/com/android/contacts/activities/ActionBarAdapter.java
index cea2ea8..27bcc7a 100644
--- a/src/com/android/contacts/activities/ActionBarAdapter.java
+++ b/src/com/android/contacts/activities/ActionBarAdapter.java
@@ -44,9 +44,9 @@
 import android.widget.SearchView.OnCloseListener;
 import android.widget.TextView;
 
-import com.android.contacts.ContactsDrawerActivity;
 import com.android.contacts.R;
 import com.android.contacts.activities.ActionBarAdapter.Listener.Action;
+import com.android.contacts.activities.PeopleActivity;
 import com.android.contacts.compat.CompatUtils;
 import com.android.contacts.list.ContactsRequest;
 import com.android.contacts.util.MaterialColorMapUtils;
@@ -507,8 +507,8 @@
             if (shouldAnimate) {
                 runStatusBarAnimation(/* colorTo */
                         MaterialColorMapUtils.getStatusBarColor(mActivity));
-            } else if (mActivity instanceof ContactsDrawerActivity) {
-                ((ContactsDrawerActivity) mActivity).updateStatusBarBackground();
+            } else if (mActivity instanceof PeopleActivity) {
+                ((PeopleActivity) mActivity).updateStatusBarBackground();
             }
         }
     }
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index 93138db..f6bbe2f 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -16,6 +16,7 @@
 
 package com.android.contacts.activities;
 
+import android.accounts.Account;
 import android.app.Fragment;
 import android.app.FragmentManager;
 import android.app.FragmentTransaction;
@@ -26,78 +27,139 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.SyncStatusObserver;
+import android.content.res.Configuration;
+import android.graphics.Color;
+import android.graphics.PorterDuff;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.provider.ContactsContract;
+import android.provider.ContactsContract.Intents;
 import android.provider.ContactsContract.ProviderStatus;
+import android.support.annotation.LayoutRes;
+import android.support.annotation.NonNull;
 import android.support.design.widget.CoordinatorLayout;
+import android.support.design.widget.NavigationView;
 import android.support.design.widget.Snackbar;
 import android.support.v4.content.ContextCompat;
 import android.support.v4.content.LocalBroadcastManager;
 import android.support.v4.view.GravityCompat;
+import android.support.v4.view.MenuItemCompat;
+import android.support.v4.widget.DrawerLayout;
 import android.support.v4.widget.SwipeRefreshLayout;
+import android.support.v7.app.ActionBarDrawerToggle;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
 import android.util.Log;
+import android.view.Gravity;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
+import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.SubMenu;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.widget.ImageButton;
+import android.widget.LinearLayout;
+import android.widget.TextView;
 import android.widget.Toast;
 
+import com.android.contacts.AppCompatContactsActivity;
 import com.android.contacts.ContactSaveService;
-import com.android.contacts.ContactsDrawerActivity;
+import com.android.contacts.ContactsUtils;
 import com.android.contacts.R;
 import com.android.contacts.compat.CompatUtils;
+import com.android.contacts.editor.ContactEditorFragment;
+import com.android.contacts.editor.SelectAccountDialogFragment;
+import com.android.contacts.group.GroupListItem;
 import com.android.contacts.group.GroupMembersFragment;
 import com.android.contacts.group.GroupMetaData;
+import com.android.contacts.group.GroupNameEditDialogFragment;
 import com.android.contacts.group.GroupUtil;
+import com.android.contacts.group.GroupsFragment;
+import com.android.contacts.group.GroupsFragment.GroupsListener;
+import com.android.contacts.interactions.AccountFiltersFragment;
+import com.android.contacts.interactions.AccountFiltersFragment.AccountFiltersListener;
+import com.android.contacts.list.AccountFilterActivity;
 import com.android.contacts.list.ContactListFilter;
+import com.android.contacts.list.ContactListFilterController;
 import com.android.contacts.list.ContactListFilterController.ContactListFilterListener;
 import com.android.contacts.list.ContactsIntentResolver;
 import com.android.contacts.list.ContactsRequest;
 import com.android.contacts.list.ContactsUnavailableFragment;
 import com.android.contacts.list.DefaultContactBrowseListFragment;
+import com.android.contacts.list.MultiSelectContactsListFragment;
 import com.android.contacts.list.ProviderStatusWatcher;
 import com.android.contacts.list.ProviderStatusWatcher.ProviderStatusListener;
 import com.android.contacts.logging.Logger;
 import com.android.contacts.logging.ScreenEvent.ScreenType;
 import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.account.AccountDisplayInfo;
+import com.android.contacts.model.account.AccountDisplayInfoFactory;
 import com.android.contacts.model.account.AccountInfo;
 import com.android.contacts.model.account.AccountWithDataSet;
+import com.android.contacts.preference.ContactsPreferenceActivity;
 import com.android.contacts.util.AccountFilterUtil;
 import com.android.contacts.util.Constants;
 import com.android.contacts.util.ImplicitIntentsUtil;
+import com.android.contacts.util.MaterialColorMapUtils;
+import com.android.contacts.util.SharedPreferenceUtil;
 import com.android.contacts.util.SyncUtil;
+import com.android.contacts.util.ViewUtil;
 import com.android.contacts.widget.FloatingActionButtonController;
 import com.android.contactsbind.FeatureHighlightHelper;
+import com.android.contactsbind.HelpUtils;
 import com.android.contactsbind.ObjectFactory;
+import com.google.common.util.concurrent.Futures;
 
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * Displays a list to browse contacts.
  */
-public class PeopleActivity extends ContactsDrawerActivity {
+public class PeopleActivity extends AppCompatContactsActivity implements
+        AccountFiltersListener,
+        GroupsListener,
+        NavigationView.OnNavigationItemSelectedListener,
+        SelectAccountDialogFragment.Listener {
+
+    /** Possible views of Contacts app. */
+    public enum ContactsView {
+        NONE,
+        ALL_CONTACTS,
+        ASSISTANT,
+        GROUP_VIEW,
+        ACCOUNT_VIEW,
+    }
 
     private static final String TAG = "PeopleActivity";
     private static final String TAG_ALL = "contacts-all";
     private static final String TAG_UNAVAILABLE = "contacts-unavailable";
     private static final String TAG_GROUP_VIEW = "contacts-groups";
+    private static final String TAG_GROUPS = "groups";
+    private static final String TAG_FILTERS = "filters";
+    private static final String TAG_SELECT_ACCOUNT_DIALOG = "selectAccountDialog";
+    private static final String TAG_GROUP_NAME_EDIT_DIALOG = "groupNameEditDialog";
+
     public static final String TAG_ASSISTANT = "contacts-assistant";
     public static final String TAG_SECOND_LEVEL = "second-level";
     public static final String TAG_THIRD_LEVEL = "third-level";
-
     public static final String TAG_DUPLICATES = "DuplicatesFragment";
     public static final String TAG_DUPLICATES_UTIL = "DuplicatesUtilFragment";
 
     private static final String KEY_GROUP_URI = "groupUri";
+    private static final String KEY_CONTACTS_VIEW = "contactsView";
+    private static final String KEY_NEW_GROUP_ACCOUNT = "newGroupAccount";
+
+    private static final long DRAWER_CLOSE_DELAY = 300L;
 
     private ContactsIntentResolver mIntentResolver;
     private ContactsRequest mRequest;
@@ -114,12 +176,14 @@
 
     private boolean mShouldSwitchToGroupView;
 
+    private ContactsView mCurrentView;
+
     private CoordinatorLayout mLayoutRoot;
 
     /**
      * Showing a list of Contacts. Also used for showing search results in search mode.
      */
-    private DefaultContactBrowseListFragment mAllFragment;
+    private DefaultContactBrowseListFragment mContactsListFragment;
 
     private GroupMembersFragment mMembersFragment;
     private Uri mGroupUri;
@@ -135,6 +199,28 @@
     private final int mInstanceId;
     private static final AtomicInteger sNextInstanceId = new AtomicInteger();
 
+    /** Navigation drawer related */
+    private ContactListFilterController mContactListFilterController;
+    private DrawerLayout mDrawerLayout;
+    private ContactsActionBarDrawerToggle mToggle;
+    private Toolbar mToolbar;
+    private NavigationView mNavigationView;
+    private GroupsFragment mGroupsFragment;
+    private AccountFiltersFragment mAccountFiltersFragment;
+
+    // The account the new group will be created under.
+    private AccountWithDataSet mNewGroupAccount;
+
+    // Recycle badge if possible
+    private TextView mAssistantNewBadge;
+
+    // Checkable menu item lookup maps. Every map declared here should be added to
+    // clearCheckedMenus() so that they can be cleared.
+    // TODO find a better way to handle selected menu item state, when switching to fragments.
+    private Map<Long, MenuItem> mGroupMenuMap = new HashMap<>();
+    private Map<ContactListFilter, MenuItem> mFilterMenuMap = new HashMap<>();
+    private Map<Integer, MenuItem> mIdMenuMap = new HashMap<>();
+
     private Object mStatusChangeListenerHandle;
 
     private final Handler mHandler = new Handler();
@@ -157,7 +243,8 @@
 
         final ContactListFilter filter = mContactListFilterController.getFilter();
         if (filter != null) {
-            final SwipeRefreshLayout swipeRefreshLayout = mAllFragment.getSwipeRefreshLayout();
+            final SwipeRefreshLayout swipeRefreshLayout =
+                    mContactsListFragment.getSwipeRefreshLayout();
             if (swipeRefreshLayout == null) {
                 if (Log.isLoggable(TAG, Log.DEBUG)) {
                     Log.d(TAG, "Can not load swipeRefreshLayout, swipeRefreshLayout is null");
@@ -204,6 +291,72 @@
         }
     };
 
+    private class ContactsActionBarDrawerToggle extends ActionBarDrawerToggle {
+        private boolean mMenuClickedBefore = SharedPreferenceUtil.getHamburgerMenuClickedBefore(
+                PeopleActivity.this);
+
+        public ContactsActionBarDrawerToggle(AppCompatActivity activity, DrawerLayout drawerLayout,
+                Toolbar toolbar, int openDrawerContentDescRes, int closeDrawerContentDescRes) {
+            super(activity, drawerLayout, toolbar, openDrawerContentDescRes,
+                    closeDrawerContentDescRes);
+        }
+
+        @Override
+        public void onDrawerOpened(View drawerView) {
+            super.onDrawerOpened(drawerView);
+            if (!mMenuClickedBefore) {
+                SharedPreferenceUtil.setHamburgerMenuClickedBefore(PeopleActivity.this);
+                mMenuClickedBefore = true;
+            }
+            invalidateOptionsMenu();
+            // Stop search and selection mode like Gmail and Keep. Otherwise, if user switches to
+            // another fragment in navigation drawer, the current search/selection mode will be
+            // overlaid by the action bar of the newly-created fragment.
+            stopSearchAndSelection();
+            updateStatusBarBackground();
+        }
+
+        private void stopSearchAndSelection() {
+            final MultiSelectContactsListFragment listFragment;
+            if (isAllContactsView() || isAccountView()) {
+                listFragment = getAllFragment();
+            } else if (isGroupView()) {
+                listFragment = getGroupFragment();
+            } else {
+                listFragment = null;
+            }
+            if (listFragment == null) {
+                return;
+            }
+            final ActionBarAdapter actionBarAdapter = listFragment.getActionBarAdapter();
+            if (actionBarAdapter == null) {
+                return;
+            }
+            if (actionBarAdapter.isSearchMode()) {
+                actionBarAdapter.setSearchMode(false);
+            } else if (actionBarAdapter.isSelectionMode()) {
+                actionBarAdapter.setSelectionMode(false);
+            }
+        }
+
+        @Override
+        public void onDrawerClosed(View view) {
+            super.onDrawerClosed(view);
+            invalidateOptionsMenu();
+        }
+
+        @Override
+        public void onDrawerStateChanged(int newState) {
+            super.onDrawerStateChanged(newState);
+            // Set transparent status bar when drawer starts to move.
+            if (newState != DrawerLayout.STATE_IDLE) {
+                updateStatusBarBackground();
+            }
+            initializeAssistantNewBadge();
+        }
+    }
+
+
     public PeopleActivity() {
         mInstanceId = sNextInstanceId.getAndIncrement();
         mIntentResolver = new ContactsIntentResolver(this);
@@ -237,6 +390,54 @@
             return;
         }
 
+        mContactListFilterController = ContactListFilterController.getInstance(this);
+        mContactListFilterController.checkFilterValidity(false);
+
+        super.setContentView(R.layout.contacts_drawer_activity);
+
+        // Set up the action bar.
+        mToolbar = getView(R.id.toolbar);
+        setSupportActionBar(mToolbar);
+
+        // Add shadow under toolbar.
+        ViewUtil.addRectangularOutlineProvider(findViewById(R.id.toolbar_parent), getResources());
+
+        // Set up hamburger button.
+        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
+        mToggle = new ContactsActionBarDrawerToggle(this, mDrawerLayout, mToolbar,
+                R.string.navigation_drawer_open, R.string.navigation_drawer_close);
+
+        mDrawerLayout.setDrawerListener(mToggle);
+        // Set fallback handler for when drawer is disabled.
+        mToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                onBackPressed();
+            }
+        });
+
+        // Set up navigation mode.
+        if (savedState != null) {
+            mCurrentView = ContactsView.values()[savedState.getInt(KEY_CONTACTS_VIEW)];
+        } else {
+            mCurrentView = ContactsView.ALL_CONTACTS;
+        }
+
+        loadGroups();
+
+        // Set up hamburger menu items.
+        mNavigationView = (NavigationView) findViewById(R.id.nav_view);
+        mNavigationView.setNavigationItemSelectedListener(this);
+        setUpMenu();
+
+        initializeAssistantNewBadge();
+        loadGroupsAndFilters();
+
+        if (savedState != null && savedState.containsKey(KEY_NEW_GROUP_ACCOUNT)) {
+            mNewGroupAccount = AccountWithDataSet.unstringify(
+                    savedState.getString(KEY_NEW_GROUP_ACCOUNT));
+        }
+
         mContactListFilterController.addListener(mFilterListener);
         mProviderStatusWatcher.addListener(mProviderStatusListener);
 
@@ -254,6 +455,32 @@
         getWindow().setBackgroundDrawable(null);
     }
 
+    private void loadGroupsAndFilters() {
+        final FragmentManager fragmentManager = getFragmentManager();
+        final FragmentTransaction transaction = fragmentManager.beginTransaction();
+        addGroupsAndFiltersFragments(transaction);
+        transaction.commitAllowingStateLoss();
+        fragmentManager.executePendingTransactions();
+    }
+
+    private void addGroupsAndFiltersFragments(FragmentTransaction transaction) {
+        final FragmentManager fragmentManager = getFragmentManager();
+        mGroupsFragment = (GroupsFragment) fragmentManager.findFragmentByTag(TAG_GROUPS);
+        if (mGroupsFragment == null) {
+            mGroupsFragment = new GroupsFragment();
+            transaction.add(mGroupsFragment, TAG_GROUPS);
+        }
+        mGroupsFragment.setListener(this);
+
+        mAccountFiltersFragment = (AccountFiltersFragment)
+                fragmentManager.findFragmentByTag(TAG_FILTERS);
+        if (mAccountFiltersFragment == null) {
+            mAccountFiltersFragment = new AccountFiltersFragment();
+            transaction.add(mAccountFiltersFragment, TAG_FILTERS);
+        }
+        mAccountFiltersFragment.setListener(this);
+    }
+
     @Override
     protected void onNewIntent(Intent intent) {
         final String action = intent.getAction();
@@ -309,8 +536,9 @@
             // Re-initialize ActionBarAdapter because {@link #onNewIntent(Intent)} doesn't invoke
             // {@link Fragment#onActivityCreated(Bundle)} where we initialize ActionBarAdapter
             // initially.
-            mAllFragment.setParameters(/* ContactsRequest */ mRequest, /* fromOnNewIntent */ true);
-            mAllFragment.initializeActionBarAdapter(null);
+            mContactsListFragment.setParameters(/* ContactsRequest */ mRequest,
+                    /* fromOnNewIntent */ true);
+            mContactsListFragment.initializeActionBarAdapter(null);
         }
 
         initializeFabVisibility();
@@ -407,22 +635,32 @@
         }
     }
 
+    @Override
+    public void setContentView(@LayoutRes int layoutResID) {
+        final ViewGroup parent = (ViewGroup) findViewById(R.id.content_frame);
+        if (parent != null) {
+            parent.removeAllViews();
+        }
+        LayoutInflater.from(this).inflate(layoutResID, parent);
+    }
+
     private void setUpAllFragment(FragmentManager fragmentManager) {
-        mAllFragment = (DefaultContactBrowseListFragment)
+        mContactsListFragment = (DefaultContactBrowseListFragment)
                 fragmentManager.findFragmentByTag(TAG_ALL);
 
-        if (mAllFragment == null) {
-            mAllFragment = new DefaultContactBrowseListFragment();
-            mAllFragment.setAnimateOnLoad(true);
+        if (mContactsListFragment == null) {
+            mContactsListFragment = new DefaultContactBrowseListFragment();
+            mContactsListFragment.setAnimateOnLoad(true);
             fragmentManager.beginTransaction()
-                    .add(R.id.contacts_list_container, mAllFragment, TAG_ALL)
+                    .add(R.id.contacts_list_container, mContactsListFragment, TAG_ALL)
                     .commit();
             fragmentManager.executePendingTransactions();
         }
 
-        mAllFragment.setContactsAvailable(areContactsAvailable());
-        mAllFragment.setListType(mContactListFilterController.getFilterListType());
-        mAllFragment.setParameters(/* ContactsRequest */ mRequest, /* fromOnNewIntent */ false);
+        mContactsListFragment.setContactsAvailable(areContactsAvailable());
+        mContactsListFragment.setListType(mContactListFilterController.getFilterListType());
+        mContactsListFragment.setParameters(/* ContactsRequest */ mRequest,
+                /* fromOnNewIntent */ false);
     }
 
     @Override
@@ -446,6 +684,10 @@
     protected void onResume() {
         super.onResume();
 
+        if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
+            updateStatusBarBackground();
+        }
+
         if (mShouldSwitchToAllContacts) {
             switchToAllContacts();
         }
@@ -468,6 +710,22 @@
                 new IntentFilter(ContactSaveService.BROADCAST_GROUP_DELETED));
     }
 
+    public void updateStatusBarBackground() {
+        updateStatusBarBackground(/* color */ -1);
+    }
+
+    public void updateStatusBarBackground(int color) {
+        if (!CompatUtils.isLollipopCompatible()) return;
+        if (color == -1) {
+            mDrawerLayout.setStatusBarBackgroundColor(
+                    MaterialColorMapUtils.getStatusBarColor(this));
+        } else {
+            mDrawerLayout.setStatusBarBackgroundColor(color);
+        }
+        mDrawerLayout.invalidate();
+        getWindow().setStatusBarColor(Color.TRANSPARENT);
+    }
+
     @Override
     protected void onDestroy() {
         mProviderStatusWatcher.removeListener(mProviderStatusListener);
@@ -491,7 +749,7 @@
     }
 
     private boolean shouldHideFab() {
-        if (mAllFragment != null && mAllFragment.getActionBarAdapter() == null
+        if (mContactsListFragment != null && mContactsListFragment.getActionBarAdapter() == null
                 || isInSecondLevel()) {
             return true;
         }
@@ -532,6 +790,25 @@
         }
     }
 
+    // Set up fragment manager to load groups.
+    protected void loadGroups() {
+        final FragmentManager fragmentManager = getFragmentManager();
+        final FragmentTransaction transaction = fragmentManager.beginTransaction();
+        addGroupsLoadingFragment(transaction);
+        transaction.commitAllowingStateLoss();
+        fragmentManager.executePendingTransactions();
+    }
+
+    private void addGroupsLoadingFragment(FragmentTransaction transaction) {
+        final FragmentManager fragmentManager = getFragmentManager();
+        mGroupsFragment = (GroupsFragment) fragmentManager.findFragmentByTag(TAG_GROUPS);
+        if (mGroupsFragment == null) {
+            mGroupsFragment = new GroupsFragment();
+            transaction.add(mGroupsFragment, TAG_GROUPS);
+        }
+        mGroupsFragment.setListener(this);
+    }
+
     private void updateViewConfiguration(boolean forceUpdate) {
         int providerStatus = mProviderStatusWatcher.getProviderStatus();
         if (!forceUpdate && (mProviderStatus != null)
@@ -545,26 +822,26 @@
         // So we need to handle the case where provider status is STATUS_EMPTY and there is
         // actually at least one real account (not "local" account) on device.
         if (shouldShowList()) {
-            if (mAllFragment != null) {
+            if (mContactsListFragment != null) {
                 final Fragment unavailableFragment = fragmentManager
                         .findFragmentByTag(TAG_UNAVAILABLE);
                 if (unavailableFragment != null) {
                     transaction.remove(unavailableFragment);
                 }
-                if (mAllFragment.isHidden()) {
-                    transaction.show(mAllFragment);
+                if (mContactsListFragment.isHidden()) {
+                    transaction.show(mContactsListFragment);
                 }
-                mAllFragment.setContactsAvailable(areContactsAvailable());
-                mAllFragment.setEnabled(true);
+                mContactsListFragment.setContactsAvailable(areContactsAvailable());
+                mContactsListFragment.setEnabled(true);
             }
         } else {
             // Setting up the page so that the user can still use the app
             // even without an account.
-            if (mAllFragment != null) {
-                mAllFragment.setEnabled(false);
+            if (mContactsListFragment != null) {
+                mContactsListFragment.setEnabled(false);
             }
             final ContactsUnavailableFragment fragment = new ContactsUnavailableFragment();
-            transaction.hide(mAllFragment);
+            transaction.hide(mContactsListFragment);
             transaction.replace(R.id.contacts_unavailable_container, fragment, TAG_UNAVAILABLE);
             fragment.updateStatus(mProviderStatus);
         }
@@ -584,8 +861,9 @@
     }
 
     private void invalidateOptionsMenuIfNeeded() {
-        if (mAllFragment != null
-                && mAllFragment.getOptionsMenuContactsAvailable() != areContactsAvailable()) {
+        if (mContactsListFragment != null
+                && mContactsListFragment.getOptionsMenuContactsAvailable()
+                != areContactsAvailable()) {
             invalidateOptionsMenu();
         }
     }
@@ -598,7 +876,7 @@
                 // If COMBINING_ACCENT is set, it's not a unicode character.
                 && ((unicodeChar & KeyCharacterMap.COMBINING_ACCENT) == 0)
                 && !Character.isWhitespace(unicodeChar)) {
-            if (mAllFragment.onKeyDown(unicodeChar)) {
+            if (mContactsListFragment.onKeyDown(unicodeChar)) {
                 return true;
             }
         }
@@ -613,8 +891,8 @@
         }
 
         // Handle the back event in drawer first.
-        if (mDrawer.isDrawerOpen(GravityCompat.START)) {
-            mDrawer.closeDrawer(GravityCompat.START);
+        if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
+            mDrawerLayout.closeDrawer(GravityCompat.START);
             return;
         }
 
@@ -629,12 +907,12 @@
             return;
         }
 
-        // If feature highlight is present, let it handle the back event before mAllFragment.
+        // If feature highlight is present, let it handle the back event before mContactsListFragment.
         if (FeatureHighlightHelper.tryRemoveHighlight(this)) {
             return;
         }
 
-        // Handle the back event in "first level" - mAllFragment.
+        // Handle the back event in "first level" - mContactsListFragment.
         if (maybeHandleInAllFragment()) {
             return;
         }
@@ -666,24 +944,24 @@
     // Returns true if back event is handled in this method.
     private boolean maybeHandleInAllFragment() {
         if (isAllFragmentInSelectionMode()) {
-            mAllFragment.getActionBarAdapter().setSelectionMode(false);
+            mContactsListFragment.getActionBarAdapter().setSelectionMode(false);
             return true;
         }
 
         if (isAllFragmentInSearchMode()) {
-            mAllFragment.getActionBarAdapter().setSearchMode(false);
-            if (mAllFragment.wasSearchResultClicked()) {
-                mAllFragment.resetSearchResultClicked();
+            mContactsListFragment.getActionBarAdapter().setSearchMode(false);
+            if (mContactsListFragment.wasSearchResultClicked()) {
+                mContactsListFragment.resetSearchResultClicked();
             } else {
                 Logger.logScreenView(this, ScreenType.SEARCH_EXIT);
-                Logger.logSearchEvent(mAllFragment.createSearchState());
+                Logger.logSearchEvent(mContactsListFragment.createSearchState());
             }
             return true;
         }
 
         if (!AccountFilterUtil.isAllContactsFilter(mContactListFilterController.getFilter())
-                && !mAllFragment.isHidden()) {
-            // If mAllFragment is hidden, then mContactsUnavailableFragment is visible so we
+                && !mContactsListFragment.isHidden()) {
+            // If mContactsListFragment is hidden, then mContactsUnavailableFragment is visible so we
             // don't need to switch to all contacts.
             switchToAllContacts();
             return true;
@@ -693,13 +971,13 @@
     }
 
     private boolean isAllFragmentInSelectionMode() {
-        return mAllFragment != null && mAllFragment.getActionBarAdapter() != null
-                && mAllFragment.getActionBarAdapter().isSelectionMode();
+        return mContactsListFragment != null && mContactsListFragment.getActionBarAdapter() != null
+                && mContactsListFragment.getActionBarAdapter().isSelectionMode();
     }
 
     private boolean isAllFragmentInSearchMode() {
-        return mAllFragment != null && mAllFragment.getActionBarAdapter() != null
-                && mAllFragment.getActionBarAdapter().isSearchMode();
+        return mContactsListFragment != null && mContactsListFragment.getActionBarAdapter() != null
+                && mContactsListFragment.getActionBarAdapter().isSearchMode();
     }
 
     private boolean isGroupsFragmentInSelectionMode() {
@@ -715,6 +993,10 @@
     @Override
     protected void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
+        if (mNewGroupAccount != null) {
+            outState.putString(KEY_NEW_GROUP_ACCOUNT, mNewGroupAccount.stringify());
+        }
+        outState.putInt(KEY_CONTACTS_VIEW, mCurrentView.ordinal());
         outState.putParcelable(KEY_GROUP_URI, mGroupUri);
     }
 
@@ -761,8 +1043,7 @@
         }
     }
 
-    @Override
-    protected void onGroupMenuItemClicked(long groupId, String title) {
+    private void onGroupMenuItemClicked(long groupId, String title) {
         if (isGroupView() && mMembersFragment != null
                 && mMembersFragment.isCurrentGroup(groupId)) {
             return;
@@ -771,9 +1052,8 @@
         switchToOrUpdateGroupView(GroupUtil.ACTION_SWITCH_GROUP);
     }
 
-    @Override
-    protected void onFilterMenuItemClicked(Intent intent) {
-        // We must pop second level first to "restart" mAllFragment, before changing filter.
+    private void onFilterMenuItemClicked(Intent intent) {
+        // We must pop second level first to "restart" mContactsListFragment before changing filter.
         if (isInSecondLevel()) {
             popSecondLevel();
             showFabWithAnimation(/* showFab */ true);
@@ -785,7 +1065,8 @@
             mContactListFilterController.setContactListFilter(current, false);
         }
         mCurrentView = ContactsView.ACCOUNT_VIEW;
-        super.onFilterMenuItemClicked(intent);
+        AccountFilterUtil.handleAccountFilterResult(mContactListFilterController,
+                AppCompatActivity.RESULT_OK, intent);
     }
 
     private void switchToOrUpdateGroupView(String action) {
@@ -797,7 +1078,6 @@
         }
     }
 
-    @Override
     protected void launchAssistant() {
         switchView(ContactsView.ASSISTANT);
     }
@@ -830,7 +1110,6 @@
         showFabWithAnimation(/* showFab */ false);
     }
 
-    @Override
     public void switchToAllContacts() {
         if (isInSecondLevel()) {
             popSecondLevel();
@@ -838,9 +1117,23 @@
         mShouldSwitchToAllContacts = false;
         mCurrentView = ContactsView.ALL_CONTACTS;
         showFabWithAnimation(/* showFab */ true);
-        mAllFragment.scrollToTop();
+        mContactsListFragment.scrollToTop();
 
-        super.switchToAllContacts();
+        resetFilter();
+
+        final Menu menu = mNavigationView.getMenu();
+        final MenuItem allContacts = menu.findItem(R.id.nav_all_contacts);
+        updateMenuSelection(allContacts);
+
+        setTitle(getString(R.string.contactsList));
+    }
+
+    private void resetFilter() {
+        final Intent intent = new Intent();
+        final ContactListFilter filter = AccountFilterUtil.createContactsFilter(this);
+        intent.putExtra(AccountFilterActivity.EXTRA_CONTACT_LIST_FILTER, filter);
+        AccountFilterUtil.handleAccountFilterResult(
+                mContactListFilterController, AppCompatActivity.RESULT_OK, intent);
     }
 
     private boolean popThirdLevel() {
@@ -862,26 +1155,23 @@
         updateStatusBarBackground(ContextCompat.getColor(this, R.color.primary_color_dark));
     }
 
-    @Override
     protected DefaultContactBrowseListFragment getAllFragment() {
-        return mAllFragment;
+        return mContactsListFragment;
     }
 
-    @Override
     protected GroupMembersFragment getGroupFragment() {
         return mMembersFragment;
     }
 
-    @Override
     protected GroupMetaData getGroupMetaData() {
         return mMembersFragment == null ? null : mMembersFragment.getGroupMetaData();
     }
 
     private void handleFilterChangeForFragment(ContactListFilter filter) {
-        if (mAllFragment.canSetActionBar()) {
-            mAllFragment.setFilterAndUpdateTitle(filter);
+        if (mContactsListFragment.canSetActionBar()) {
+            mContactsListFragment.setFilterAndUpdateTitle(filter);
             // Scroll to top after filter is changed.
-            mAllFragment.scrollToTop();
+            mContactsListFragment.scrollToTop();
         }
     }
 
@@ -903,4 +1193,367 @@
         }
         invalidateOptionsMenu();
     }
+
+    private void initializeAssistantNewBadge() {
+        if (mNavigationView == null) {
+            return;
+        }
+        final MenuItem assistantMenu = mNavigationView.getMenu().findItem(R.id.nav_assistant);
+        if (assistantMenu == null) {
+            return;
+        }
+        final LinearLayout newBadgeFrame =
+                (LinearLayout) MenuItemCompat.getActionView(assistantMenu);
+        final boolean showWelcomeBadge = !SharedPreferenceUtil.isWelcomeCardDismissed(this);
+        if (showWelcomeBadge && newBadgeFrame.getChildCount() == 0) {
+            if (mAssistantNewBadge == null) {
+                mAssistantNewBadge = (TextView) LayoutInflater.from(this)
+                        .inflate(R.layout.assistant_new_badge, null);
+            }
+            newBadgeFrame.setGravity(Gravity.CENTER_VERTICAL);
+            newBadgeFrame.addView(mAssistantNewBadge);
+        } else if (!showWelcomeBadge && newBadgeFrame.getChildCount() > 0) {
+            newBadgeFrame.removeAllViews();
+        }
+    }
+
+    public void setDrawerLockMode(boolean enabled) {
+        // Prevent drawer from being opened by sliding from the start of screen.
+        mDrawerLayout.setDrawerLockMode(enabled ? DrawerLayout.LOCK_MODE_UNLOCKED
+                : DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
+
+        // Order of these statements matter.
+        // Display back button and disable drawer indicator.
+        if (enabled) {
+            getSupportActionBar().setDisplayHomeAsUpEnabled(false);
+            mToggle.setDrawerIndicatorEnabled(true);
+        } else {
+            mToggle.setDrawerIndicatorEnabled(false);
+            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+        }
+    }
+
+    private void setUpMenu() {
+        final Menu menu = mNavigationView.getMenu();
+
+        if (ObjectFactory.getAssistantFragment() == null) {
+            menu.removeItem(R.id.nav_assistant);
+        } else {
+            final int id = R.id.nav_assistant;
+            final MenuItem assistantMenu = menu.findItem(id);
+            mIdMenuMap.put(id, assistantMenu);
+            if (isAssistantView()) {
+                updateMenuSelection(assistantMenu);
+            }
+        }
+
+        if (!HelpUtils.isHelpAndFeedbackAvailable()) {
+            menu.removeItem(R.id.nav_help);
+        }
+
+        final MenuItem allContactsMenu = menu.findItem(R.id.nav_all_contacts);
+        mIdMenuMap.put(R.id.nav_all_contacts, allContactsMenu);
+        if (isAllContactsView()) {
+            updateMenuSelection(allContactsMenu);
+        }
+    }
+
+    public Toolbar getToolbar() {
+        return mToolbar;
+    }
+
+    @Override
+    protected void onPostCreate(Bundle savedInstanceState) {
+        super.onPostCreate(savedInstanceState);
+        mToggle.syncState();
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        mToggle.onConfigurationChanged(newConfig);
+    }
+
+    @Override
+    public void onGroupsLoaded(List<GroupListItem> groupListItems,
+            boolean areGroupWritableAccountsAvailable) {
+        final Menu menu = mNavigationView.getMenu();
+        final MenuItem groupsMenuItem = menu.findItem(R.id.nav_groups);
+        final SubMenu subMenu = groupsMenuItem.getSubMenu();
+        subMenu.removeGroup(R.id.nav_groups_items);
+        mGroupMenuMap = new HashMap<>();
+
+        final GroupMetaData groupMetaData = getGroupMetaData();
+
+        if (groupListItems != null) {
+            // Add each group
+            for (final GroupListItem groupListItem : groupListItems) {
+                if (GroupUtil.isEmptyFFCGroup(groupListItem)) {
+                    continue;
+                }
+                final String title = groupListItem.getTitle();
+                final MenuItem menuItem =
+                        subMenu.add(R.id.nav_groups_items, Menu.NONE, Menu.NONE, title);
+                mGroupMenuMap.put(groupListItem.getGroupId(), menuItem);
+                if (isGroupView() && groupMetaData != null
+                        && groupMetaData.groupId == groupListItem.getGroupId()) {
+                    updateMenuSelection(menuItem);
+                }
+                menuItem.setIcon(R.drawable.quantum_ic_label_vd_theme_24);
+                menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
+                    @Override
+                    public boolean onMenuItemClick(MenuItem item) {
+                        onGroupMenuItemClicked(groupListItem.getGroupId(),
+                                groupListItem.getTitle());
+                        updateMenuSelection(menuItem);
+                        mDrawerLayout.closeDrawer(GravityCompat.START);
+                        return true;
+                    }
+                });
+
+                updateMenuContentDescription(menuItem,
+                        getString(R.string.group_edit_field_hint_text));
+            }
+        }
+
+        // Don't show "Create label" menu if there's no group-writable accounts available.
+        if (!areGroupWritableAccountsAvailable) {
+            return;
+        }
+
+        // Create a menu item in the sub menu to add new groups
+        final MenuItem menuItem = subMenu.add(R.id.nav_groups_items, Menu.NONE,
+                Menu.NONE, getString(R.string.menu_new_group_action_bar));
+        menuItem.setIcon(R.drawable.quantum_ic_add_vd_theme_24);
+        menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
+            @Override
+            public boolean onMenuItemClick(MenuItem item) {
+                onCreateGroupMenuItemClicked();
+                mDrawerLayout.closeDrawer(GravityCompat.START);
+                return true;
+            }
+        });
+
+        if (isGroupView() && groupMetaData != null) {
+            updateGroupMenu(groupMetaData);
+        }
+    }
+
+    public void updateGroupMenu(GroupMetaData groupMetaData) {
+        clearCheckedMenus();
+        if (groupMetaData != null && mGroupMenuMap != null
+                && mGroupMenuMap.get(groupMetaData.groupId) != null) {
+            setMenuChecked(mGroupMenuMap.get(groupMetaData.groupId), true);
+        }
+    }
+
+    private void updateMenuContentDescription(MenuItem menuItem, CharSequence contentDescription) {
+        // Create a dummy action view to attach extra hidden content description to the menuItem
+        // for Talkback. We want Talkback to read out the account type but not have it be part
+        // of the menuItem title.
+        final LinearLayout view = (LinearLayout) LayoutInflater.from(this)
+                .inflate(R.layout.menu_item_action_view, null);
+        view.setContentDescription(contentDescription);
+        view.setVisibility(View.VISIBLE);
+        menuItem.setActionView(view);
+    }
+
+    protected void onCreateGroupMenuItemClicked() {
+        // Select the account to create the group
+        final Bundle extras = getIntent().getExtras();
+        final Account account = extras == null ? null :
+                (Account) extras.getParcelable(Intents.Insert.EXTRA_ACCOUNT);
+        if (account == null) {
+            selectAccountForNewGroup();
+        } else {
+            final String dataSet = extras == null
+                    ? null : extras.getString(Intents.Insert.EXTRA_DATA_SET);
+            final AccountWithDataSet accountWithDataSet = new AccountWithDataSet(
+                    account.name, account.type, dataSet);
+            onAccountChosen(accountWithDataSet, /* extraArgs */ null);
+        }
+    }
+
+    private void selectAccountForNewGroup() {
+        // This should never block because the GroupsFragment loads the accounts and the
+        // "Create Label" item only exists when that loading finishes
+        final List<AccountInfo> accounts = Futures.getUnchecked(AccountTypeManager.getInstance(this)
+                .filterAccountsAsync(AccountTypeManager.AccountFilter.GROUPS_WRITABLE));
+        if (accounts.isEmpty()) {
+            // We shouldn't present the add group button if there are no writable accounts
+            // but check it since it's possible we are started with an Intent.
+            Toast.makeText(this, R.string.groupCreateFailedToast, Toast.LENGTH_SHORT).show();
+            return;
+        }
+        // If there is a single writable account, use it w/o showing a dialog.
+        if (accounts.size() == 1) {
+            onAccountChosen(accounts.get(0).getAccount(), /* extraArgs */ null);
+            return;
+        }
+        SelectAccountDialogFragment.show(getFragmentManager(), R.string.dialog_new_group_account,
+                AccountTypeManager.AccountFilter.GROUPS_WRITABLE, /* extraArgs */ null,
+                TAG_SELECT_ACCOUNT_DIALOG);
+    }
+
+    @Override
+    public void onAccountChosen(AccountWithDataSet account, Bundle extraArgs) {
+        mNewGroupAccount = account;
+        GroupNameEditDialogFragment.newInstanceForCreation(
+                mNewGroupAccount, GroupUtil.ACTION_CREATE_GROUP)
+                .show(getFragmentManager(), TAG_GROUP_NAME_EDIT_DIALOG);
+    }
+
+    @Override
+    public void onAccountSelectorCancelled() {
+    }
+
+    @Override
+    public void onFiltersLoaded(List<ContactListFilter> accountFilterItems) {
+        final AccountDisplayInfoFactory accountDisplayFactory = AccountDisplayInfoFactory.
+                fromListFilters(this, accountFilterItems);
+
+        final Menu menu = mNavigationView.getMenu();
+        final MenuItem filtersMenuItem = menu.findItem(R.id.nav_filters);
+        final SubMenu subMenu = filtersMenuItem.getSubMenu();
+        subMenu.removeGroup(R.id.nav_filters_items);
+        mFilterMenuMap = new HashMap<>();
+
+        if (accountFilterItems == null || accountFilterItems.size() < 2) {
+            return;
+        }
+
+        for (int i = 0; i < accountFilterItems.size(); i++) {
+            final ContactListFilter filter = accountFilterItems.get(i);
+            final AccountDisplayInfo displayableAccount =
+                    accountDisplayFactory.getAccountDisplayInfoFor(filter);
+            final CharSequence menuName = displayableAccount.getNameLabel();
+            final MenuItem menuItem = subMenu.add(R.id.nav_filters_items, Menu.NONE,
+                    Menu.NONE, menuName);
+            if (isAccountView() && filter == mContactListFilterController.getFilter()) {
+                updateMenuSelection(menuItem);
+            }
+            mFilterMenuMap.put(filter, menuItem);
+            final Intent intent = new Intent();
+            intent.putExtra(AccountFilterActivity.EXTRA_CONTACT_LIST_FILTER, filter);
+            menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
+                @Override
+                public boolean onMenuItemClick(MenuItem item) {
+                    onFilterMenuItemClicked(intent);
+                    updateMenuSelection(menuItem);
+                    mDrawerLayout.closeDrawer(GravityCompat.START);
+                    return true;
+                }
+            });
+            if (displayableAccount.getIcon() != null) {
+                menuItem.setIcon(displayableAccount.getIcon());
+                // Get rid of the default menu item overlay and show original account icons.
+                menuItem.getIcon().setColorFilter(Color.TRANSPARENT, PorterDuff.Mode.SRC_ATOP);
+            }
+
+            updateMenuContentDescription(menuItem, displayableAccount.getTypeLabel());
+        }
+
+        if (isAccountView()) {
+            updateFilterMenu(mContactListFilterController.getFilter());
+        }
+    }
+
+    public void updateFilterMenu(ContactListFilter filter) {
+        clearCheckedMenus();
+        if (filter != null && filter.isContactsFilterType()) {
+            if (mIdMenuMap != null && mIdMenuMap.get(R.id.nav_all_contacts) != null) {
+                setMenuChecked(mIdMenuMap.get(R.id.nav_all_contacts), true);
+            }
+        } else {
+            if (mFilterMenuMap != null && mFilterMenuMap.get(filter) != null) {
+                setMenuChecked(mFilterMenuMap.get(filter), true);
+            }
+        }
+    }
+
+    private void clearCheckedMenus() {
+        clearCheckedMenu(mFilterMenuMap);
+        clearCheckedMenu(mGroupMenuMap);
+        clearCheckedMenu(mIdMenuMap);
+    }
+
+    private void clearCheckedMenu(Map<?, MenuItem> map) {
+        final Iterator it = map.entrySet().iterator();
+        while (it.hasNext()) {
+            Map.Entry pair = (Map.Entry) it.next();
+            setMenuChecked(map.get(pair.getKey()), false);
+        }
+    }
+
+    private void setMenuChecked(MenuItem menuItem, boolean checked) {
+        if (menuItem == null) {
+            return;
+        }
+        menuItem.setCheckable(checked);
+        menuItem.setChecked(checked);
+    }
+
+    public boolean isGroupView() {
+        return mCurrentView == ContactsView.GROUP_VIEW;
+    }
+
+    protected boolean isAssistantView() {
+        return mCurrentView == ContactsView.ASSISTANT;
+    }
+
+    protected boolean isAllContactsView() {
+        return mCurrentView == ContactsView.ALL_CONTACTS;
+    }
+
+    protected boolean isAccountView() {
+        return mCurrentView == ContactsView.ACCOUNT_VIEW;
+    }
+
+    public boolean isInSecondLevel() {
+        return isGroupView() || isAssistantView();
+    }
+
+    @Override
+    public boolean onNavigationItemSelected(@NonNull final MenuItem item) {
+        final int id = item.getItemId();
+
+        if (id == R.id.nav_settings) {
+            new Handler().postDelayed(new Runnable() {
+                @Override
+                public void run() {
+                    startActivity(createPreferenceIntent());
+                }
+            }, DRAWER_CLOSE_DELAY);
+        } else if (id == R.id.nav_help) {
+            HelpUtils.launchHelpAndFeedbackForMainScreen(this);
+        } else if (id == R.id.nav_all_contacts) {
+            switchToAllContacts();
+        } else if (id == R.id.nav_assistant) {
+            if (!isAssistantView()) {
+                launchAssistant();
+                updateMenuSelection(item);
+            }
+        } else if (item.getIntent() != null) {
+            ImplicitIntentsUtil.startActivityInApp(this, item.getIntent());
+        } else {
+            Log.w(TAG, "Unhandled navigation view item selection");
+        }
+
+        mDrawerLayout.closeDrawer(GravityCompat.START);
+        return true;
+    }
+
+    private void updateMenuSelection(MenuItem menuItem) {
+        clearCheckedMenus();
+        setMenuChecked(menuItem, true);
+    }
+
+    private Intent createPreferenceIntent() {
+        final Intent intent = new Intent(this, ContactsPreferenceActivity.class);
+        intent.putExtra(ContactsPreferenceActivity.EXTRA_NEW_LOCAL_PROFILE,
+                ContactEditorFragment.INTENT_EXTRA_NEW_LOCAL_PROFILE);
+        return intent;
+    }
+
+
 }
diff --git a/src/com/android/contacts/group/GroupMembersFragment.java b/src/com/android/contacts/group/GroupMembersFragment.java
index 004e0f4..31938d7 100644
--- a/src/com/android/contacts/group/GroupMembersFragment.java
+++ b/src/com/android/contacts/group/GroupMembersFragment.java
@@ -49,11 +49,11 @@
 import android.widget.Toast;
 
 import com.android.contacts.ContactSaveService;
-import com.android.contacts.ContactsDrawerActivity;
 import com.android.contacts.ContactsUtils;
 import com.android.contacts.GroupMetaDataLoader;
 import com.android.contacts.R;
 import com.android.contacts.activities.ActionBarAdapter;
+import com.android.contacts.activities.PeopleActivity;
 import com.android.contacts.group.GroupMembersAdapter.GroupMembersQuery;
 import com.android.contacts.interactions.GroupDeletionDialogFragment;
 import com.android.contacts.list.ContactsRequest;
@@ -220,7 +220,7 @@
 
     private ActionBarAdapter mActionBarAdapter;
 
-    private ContactsDrawerActivity mActivity;
+    private PeopleActivity mActivity;
 
     private Uri mGroupUri;
 
@@ -614,7 +614,7 @@
     @Override
     public void onActivityCreated(Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
-        mActivity = (ContactsDrawerActivity) getActivity();
+        mActivity = (PeopleActivity) getActivity();
         mActionBarAdapter = new ActionBarAdapter(mActivity, mActionBarListener,
                 mActivity.getSupportActionBar(), mActivity.getToolbar(),
                         R.string.enter_contact_name);
diff --git a/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java b/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java
index 5c5609d..01361b2 100644
--- a/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java
+++ b/src/com/android/contacts/interactions/GroupDeletionDialogFragment.java
@@ -23,8 +23,8 @@
 import android.os.Bundle;
 
 import com.android.contacts.ContactSaveService;
-import com.android.contacts.ContactsDrawerActivity;
 import com.android.contacts.R;
+import com.android.contacts.activities.PeopleActivity;
 
 /**
  * A dialog for deleting a group.
@@ -65,7 +65,7 @@
 
     protected void deleteGroup() {
         final long groupId = getArguments().getLong(ARG_GROUP_ID);
-        final ContactsDrawerActivity activity = ((ContactsDrawerActivity) getActivity());
+        final PeopleActivity activity = ((PeopleActivity) getActivity());
         activity.startService(ContactSaveService.createGroupDeletionIntent(
                 getActivity(), groupId));
         activity.switchToAllContacts();
diff --git a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
index e16b2ca..f4d244e 100644
--- a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
@@ -57,7 +57,6 @@
 import android.widget.Toast;
 
 import com.android.contacts.ContactSaveService;
-import com.android.contacts.ContactsDrawerActivity;
 import com.android.contacts.Experiments;
 import com.android.contacts.R;
 import com.android.contacts.activities.ActionBarAdapter;
@@ -154,7 +153,7 @@
     private boolean mSearchResultClicked;
 
     private ActionBarAdapter mActionBarAdapter;
-    private ContactsDrawerActivity mActivity;
+    private PeopleActivity mActivity;
     private ContactsRequest mContactsRequest;
     private ContactListFilterController mContactListFilterController;
 
@@ -661,7 +660,7 @@
     public void onActivityCreated(Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
 
-        mActivity = (ContactsDrawerActivity) getActivity();
+        mActivity = (PeopleActivity) getActivity();
         mActionBarAdapter = new ActionBarAdapter(mActivity, mActionBarListener,
                 mActivity.getSupportActionBar(), mActivity.getToolbar(),
                 R.string.enter_contact_name);
diff --git a/src/com/android/contacts/util/MaterialColorMapUtils.java b/src/com/android/contacts/util/MaterialColorMapUtils.java
index b54ec0e..39f69c2 100644
--- a/src/com/android/contacts/util/MaterialColorMapUtils.java
+++ b/src/com/android/contacts/util/MaterialColorMapUtils.java
@@ -24,8 +24,8 @@
 import android.os.Trace;
 import android.support.v4.content.ContextCompat;
 
-import com.android.contacts.ContactsDrawerActivity;
 import com.android.contacts.R;
+import com.android.contacts.activities.PeopleActivity;
 
 public class MaterialColorMapUtils {
     private final TypedArray sPrimaryColors;
@@ -185,8 +185,8 @@
      * Returns status bar color for group view and non-group views.
      */
     public static int getStatusBarColor(Activity activity) {
-        final boolean isGroupView = activity instanceof ContactsDrawerActivity
-                && ((ContactsDrawerActivity) activity).isGroupView();
+        final boolean isGroupView = activity instanceof PeopleActivity
+                && ((PeopleActivity) activity).isGroupView();
         return isGroupView
                 ? ContextCompat.getColor(activity, R.color.group_primary_color_dark)
                 : ContextCompat.getColor(activity, R.color.primary_color_dark);
@@ -196,8 +196,8 @@
      * Returns toolbar color for group view and non-group views.
      */
     public static int getToolBarColor(Activity activity) {
-        final boolean isGroupView = activity instanceof ContactsDrawerActivity
-                && ((ContactsDrawerActivity) activity).isGroupView();
+        final boolean isGroupView = activity instanceof PeopleActivity
+                && ((PeopleActivity) activity).isGroupView();
         return isGroupView
                 ? ContextCompat.getColor(activity, R.color.group_primary_color)
                 : ContextCompat.getColor(activity, R.color.primary_color);