/*
 * Copyright (C) 2015 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 android.widget.cts;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;

import android.app.Instrumentation;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.SystemClock;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toolbar;
import android.widget.cts.util.TestUtils;

import androidx.test.InstrumentationRegistry;
import androidx.test.annotation.UiThreadTest;
import androidx.test.filters.MediumTest;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;

import com.android.compatibility.common.util.WidgetTestUtils;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

@MediumTest
@RunWith(AndroidJUnit4.class)
public class ToolbarTest {
    private Instrumentation mInstrumentation;
    private ToolbarCtsActivity mActivity;
    private Toolbar mMainToolbar;

    @Rule
    public ActivityTestRule<ToolbarCtsActivity> mActivityRule =
            new ActivityTestRule<>(ToolbarCtsActivity.class);

    @Before
    public void setup() {
        mInstrumentation = InstrumentationRegistry.getInstrumentation();
        mActivity = mActivityRule.getActivity();
        mMainToolbar = mActivity.getMainToolbar();
    }

    @Test
    public void testConstructor() {
        new Toolbar(mActivity);

        new Toolbar(mActivity, null);

        new Toolbar(mActivity, null, android.R.attr.toolbarStyle);

        new Toolbar(mActivity, null, 0, android.R.style.Widget_Material_Toolbar);
    }

    @Test
    public void testTitleAndSubtitleContent() throws Throwable {
        // Note that this method is *not* annotated to run on the UI thread, and every
        // call to setTitle / setSubtitle is wrapped to wait until the next draw pass
        // of our main toolbar. While this is not strictly necessary to check the result
        // of getTitle / getSubtitle, this logic follows the path of deferred layout
        // and invalidation of the TextViews that show the title / subtitle in the Toolbar.

        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.setTitle(R.string.toolbar_title));
        assertEquals(mActivity.getString(R.string.toolbar_title), mMainToolbar.getTitle());

        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.setTitle("New title"));
        assertEquals("New title", mMainToolbar.getTitle());

        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.setSubtitle(R.string.toolbar_subtitle));
        assertEquals(mActivity.getString(R.string.toolbar_subtitle), mMainToolbar.getSubtitle());

        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.setSubtitle("New subtitle"));
        assertEquals("New subtitle", mMainToolbar.getSubtitle());
    }

    @Test
    public void testTitleAndSubtitleAppearance() throws Throwable {
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.setTitle(R.string.toolbar_title));
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.setSubtitle(R.string.toolbar_subtitle));

        // Since there are no APIs to get reference to the underlying implementation of
        // title and subtitle, here we are testing that calling the relevant APIs doesn't crash

        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.setTitleTextColor(Color.RED));
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.setSubtitleTextColor(Color.BLUE));

        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.setTitleTextAppearance(
                        mActivity, R.style.TextAppearance_NotColors));
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.setSubtitleTextAppearance(
                        mActivity, R.style.TextAppearance_WithColor));
    }

    @Test
    public void testMenuContent() throws Throwable {
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.inflateMenu(R.menu.toolbar_menu));

        final Menu menu = mMainToolbar.getMenu();

        assertEquals(6, menu.size());
        assertEquals(R.id.action_highlight, menu.getItem(0).getItemId());
        assertEquals(R.id.action_edit, menu.getItem(1).getItemId());
        assertEquals(R.id.action_delete, menu.getItem(2).getItemId());
        assertEquals(R.id.action_ignore, menu.getItem(3).getItemId());
        assertEquals(R.id.action_share, menu.getItem(4).getItemId());
        assertEquals(R.id.action_print, menu.getItem(5).getItemId());

        assertFalse(mMainToolbar.hasExpandedActionView());

        Toolbar.OnMenuItemClickListener menuItemClickListener =
                mock(Toolbar.OnMenuItemClickListener.class);
        mMainToolbar.setOnMenuItemClickListener(menuItemClickListener);

        menu.performIdentifierAction(R.id.action_highlight, 0);
        verify(menuItemClickListener, times(1)).onMenuItemClick(
                menu.findItem(R.id.action_highlight));

        menu.performIdentifierAction(R.id.action_share, 0);
        verify(menuItemClickListener, times(1)).onMenuItemClick(
                menu.findItem(R.id.action_share));
    }

    @Test
    public void testMenuOverflowShowHide() throws Throwable {
        // Inflate menu and check that we're not showing overflow menu yet
        mActivityRule.runOnUiThread(() -> mMainToolbar.inflateMenu(R.menu.toolbar_menu));
        assertFalse(mMainToolbar.isOverflowMenuShowing());

        // Ask to show overflow menu and check that it's showing
        mActivityRule.runOnUiThread(() -> mMainToolbar.showOverflowMenu());
        mInstrumentation.waitForIdleSync();
        assertTrue(mMainToolbar.isOverflowMenuShowing());

        // Ask to hide the overflow menu and check that it's not showing
        mActivityRule.runOnUiThread(() -> mMainToolbar.hideOverflowMenu());
        mInstrumentation.waitForIdleSync();
        assertFalse(mMainToolbar.isOverflowMenuShowing());
    }

    @Test
    public void testMenuOverflowSubmenu() throws Throwable {
        // Inflate menu and check that we're not showing overflow menu yet
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.inflateMenu(R.menu.toolbar_menu));
        assertFalse(mMainToolbar.isOverflowMenuShowing());

        // Ask to show overflow menu and check that it's showing
        mActivityRule.runOnUiThread(mMainToolbar::showOverflowMenu);
        mInstrumentation.waitForIdleSync();
        assertTrue(mMainToolbar.isOverflowMenuShowing());

        // Register a mock menu item click listener on the toolbar
        Toolbar.OnMenuItemClickListener menuItemClickListener =
                mock(Toolbar.OnMenuItemClickListener.class);
        mMainToolbar.setOnMenuItemClickListener(menuItemClickListener);

        final Menu menu = mMainToolbar.getMenu();

        // Ask to "perform" the share action and check that the menu click listener has
        // been notified
        mActivityRule.runOnUiThread(() -> menu.performIdentifierAction(R.id.action_share, 0));
        verify(menuItemClickListener, times(1)).onMenuItemClick(
                menu.findItem(R.id.action_share));

        // Ask to dismiss all the popups and check that we're not showing the overflow menu
        mActivityRule.runOnUiThread(mMainToolbar::dismissPopupMenus);
        mInstrumentation.waitForIdleSync();
        assertFalse(mMainToolbar.isOverflowMenuShowing());
    }

    @Test
    public void testMenuOverflowIcon() throws Throwable {
        // Inflate menu and check that we're not showing overflow menu yet
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.inflateMenu(R.menu.toolbar_menu));

        final Drawable overflowIcon = mActivity.getDrawable(R.drawable.icon_red);
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.setOverflowIcon(overflowIcon));

        final Drawable toolbarOverflowIcon = mMainToolbar.getOverflowIcon();
        TestUtils.assertAllPixelsOfColor("Overflow icon is red", toolbarOverflowIcon,
                toolbarOverflowIcon.getIntrinsicWidth(), toolbarOverflowIcon.getIntrinsicHeight(),
                true, Color.RED, 1, false);
    }

    @Test
    public void testActionView() throws Throwable {
        // Inflate menu and check that we don't have an expanded action view
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.inflateMenu(R.menu.toolbar_menu_search));
        assertFalse(mMainToolbar.hasExpandedActionView());

        // Expand search menu item's action view and verify that main toolbar has an expanded
        // action view
        final MenuItem searchMenuItem = mMainToolbar.getMenu().findItem(R.id.action_search);
        mActivityRule.runOnUiThread(searchMenuItem::expandActionView);
        mInstrumentation.waitForIdleSync();
        assertTrue(searchMenuItem.isActionViewExpanded());
        assertTrue(mMainToolbar.hasExpandedActionView());

        // Collapse search menu item's action view and verify that main toolbar doesn't have an
        // expanded action view
        mActivityRule.runOnUiThread(searchMenuItem::collapseActionView);
        mInstrumentation.waitForIdleSync();
        assertFalse(searchMenuItem.isActionViewExpanded());
        assertFalse(mMainToolbar.hasExpandedActionView());

        // Expand search menu item's action view again
        mActivityRule.runOnUiThread(searchMenuItem::expandActionView);
        mInstrumentation.waitForIdleSync();
        assertTrue(searchMenuItem.isActionViewExpanded());
        assertTrue(mMainToolbar.hasExpandedActionView());

        // Now collapse search menu item's action view via toolbar's API and verify that main
        // toolbar doesn't have an expanded action view
        mActivityRule.runOnUiThread(mMainToolbar::collapseActionView);
        mInstrumentation.waitForIdleSync();
        assertFalse(searchMenuItem.isActionViewExpanded());
        assertFalse(mMainToolbar.hasExpandedActionView());
    }

    @Test
    public void testNavigationConfiguration() throws Throwable {
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.setNavigationIcon(R.drawable.icon_green));
        Drawable toolbarNavigationIcon = mMainToolbar.getNavigationIcon();
        TestUtils.assertAllPixelsOfColor("Navigation icon is green", toolbarNavigationIcon,
                toolbarNavigationIcon.getIntrinsicWidth(),
                toolbarNavigationIcon.getIntrinsicHeight(),
                true, Color.GREEN, 1, false);

        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.setNavigationIcon(mActivity.getDrawable(R.drawable.icon_blue)));
        toolbarNavigationIcon = mMainToolbar.getNavigationIcon();
        TestUtils.assertAllPixelsOfColor("Navigation icon is blue", toolbarNavigationIcon,
                toolbarNavigationIcon.getIntrinsicWidth(),
                toolbarNavigationIcon.getIntrinsicHeight(),
                true, Color.BLUE, 1, false);

        mActivityRule.runOnUiThread(
                () -> mMainToolbar.setNavigationContentDescription(R.string.toolbar_navigation));
        assertEquals(mActivity.getResources().getString(R.string.toolbar_navigation),
                mMainToolbar.getNavigationContentDescription());

        mActivityRule.runOnUiThread(
                () -> mMainToolbar.setNavigationContentDescription("Navigation legend"));
        assertEquals("Navigation legend", mMainToolbar.getNavigationContentDescription());
    }

    @Test
    public void testLogoConfiguration() throws Throwable {
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.setLogo(R.drawable.icon_yellow));
        Drawable toolbarLogo = mMainToolbar.getLogo();
        TestUtils.assertAllPixelsOfColor("Logo is yellow", toolbarLogo,
                toolbarLogo.getIntrinsicWidth(),
                toolbarLogo.getIntrinsicHeight(),
                true, Color.YELLOW, 1, false);

        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.setLogo(mActivity.getDrawable(R.drawable.icon_red)));
        toolbarLogo = mMainToolbar.getLogo();
        TestUtils.assertAllPixelsOfColor("Logo is red", toolbarLogo,
                toolbarLogo.getIntrinsicWidth(),
                toolbarLogo.getIntrinsicHeight(),
                true, Color.RED, 1, false);

        mActivityRule.runOnUiThread(
                () -> mMainToolbar.setLogoDescription(R.string.toolbar_logo));
        assertEquals(mActivity.getResources().getString(R.string.toolbar_logo),
                mMainToolbar.getLogoDescription());

        mActivityRule.runOnUiThread(
                () -> mMainToolbar.setLogoDescription("Logo legend"));
        assertEquals("Logo legend", mMainToolbar.getLogoDescription());
    }

    @UiThreadTest
    @Test
    public void testContentInsetsLtr() {
        mMainToolbar.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);

        mMainToolbar.setContentInsetsAbsolute(20, 25);
        assertEquals(20, mMainToolbar.getContentInsetLeft());
        assertEquals(20, mMainToolbar.getContentInsetStart());
        assertEquals(25, mMainToolbar.getContentInsetRight());
        assertEquals(25, mMainToolbar.getContentInsetEnd());

        mMainToolbar.setContentInsetsRelative(40, 20);
        assertEquals(40, mMainToolbar.getContentInsetLeft());
        assertEquals(40, mMainToolbar.getContentInsetStart());
        assertEquals(20, mMainToolbar.getContentInsetRight());
        assertEquals(20, mMainToolbar.getContentInsetEnd());
    }

    @UiThreadTest
    @Test
    public void testContentInsetsRtl() {
        mMainToolbar.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);

        mMainToolbar.setContentInsetsAbsolute(20, 25);
        assertEquals(20, mMainToolbar.getContentInsetLeft());
        assertEquals(25, mMainToolbar.getContentInsetStart());
        assertEquals(25, mMainToolbar.getContentInsetRight());
        assertEquals(20, mMainToolbar.getContentInsetEnd());

        mMainToolbar.setContentInsetsRelative(40, 20);
        assertEquals(20, mMainToolbar.getContentInsetLeft());
        assertEquals(40, mMainToolbar.getContentInsetStart());
        assertEquals(40, mMainToolbar.getContentInsetRight());
        assertEquals(20, mMainToolbar.getContentInsetEnd());
    }

    @Test
    public void testCurrentContentInsetsLtr() throws Throwable {
        mActivityRule.runOnUiThread(
                () -> mMainToolbar.setLayoutDirection(View.LAYOUT_DIRECTION_LTR));

        mActivityRule.runOnUiThread(() -> mMainToolbar.setContentInsetsRelative(20, 25));
        assertEquals(20, mMainToolbar.getCurrentContentInsetLeft());
        assertEquals(20, mMainToolbar.getCurrentContentInsetStart());
        assertEquals(25, mMainToolbar.getCurrentContentInsetRight());
        assertEquals(25, mMainToolbar.getCurrentContentInsetEnd());

        mActivityRule.runOnUiThread(() -> mMainToolbar.setContentInsetStartWithNavigation(50));
        assertEquals(50, mMainToolbar.getContentInsetStartWithNavigation());
        // Since we haven't configured the navigation icon itself, the current content insets
        // should stay the same
        assertEquals(20, mMainToolbar.getCurrentContentInsetLeft());
        assertEquals(20, mMainToolbar.getCurrentContentInsetStart());
        assertEquals(25, mMainToolbar.getCurrentContentInsetRight());
        assertEquals(25, mMainToolbar.getCurrentContentInsetEnd());

        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.setNavigationIcon(R.drawable.icon_green));
        assertEquals(50, mMainToolbar.getContentInsetStartWithNavigation());
        // Since we have configured the navigation icon, and the currently set start inset with
        // navigation is bigger than currently set start content inset, we should be getting that
        // bigger value now
        assertEquals(50, mMainToolbar.getCurrentContentInsetLeft());
        assertEquals(50, mMainToolbar.getCurrentContentInsetStart());
        assertEquals(25, mMainToolbar.getCurrentContentInsetRight());
        assertEquals(25, mMainToolbar.getCurrentContentInsetEnd());

        mActivityRule.runOnUiThread(() -> mMainToolbar.setContentInsetEndWithActions(35));
        assertEquals(35, mMainToolbar.getContentInsetEndWithActions());
        // Since we haven't configured the menu content, the current content insets
        // should stay the same
        assertEquals(50, mMainToolbar.getCurrentContentInsetLeft());
        assertEquals(50, mMainToolbar.getCurrentContentInsetStart());
        assertEquals(25, mMainToolbar.getCurrentContentInsetRight());
        assertEquals(25, mMainToolbar.getCurrentContentInsetEnd());

        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.inflateMenu(R.menu.toolbar_menu));
        assertEquals(35, mMainToolbar.getContentInsetEndWithActions());
        // Since we have configured the menu content, and the currently set start inset with
        // navigation is bigger than currently set end content inset, we should be getting that
        // bigger value now
        assertEquals(50, mMainToolbar.getCurrentContentInsetLeft());
        assertEquals(50, mMainToolbar.getCurrentContentInsetStart());
        assertEquals(35, mMainToolbar.getCurrentContentInsetRight());
        assertEquals(35, mMainToolbar.getCurrentContentInsetEnd());
    }

    @Test
    public void testCurrentContentInsetsRtl() throws Throwable {
        mActivityRule.runOnUiThread(
                () -> mMainToolbar.setLayoutDirection(View.LAYOUT_DIRECTION_RTL));

        mActivityRule.runOnUiThread(() -> mMainToolbar.setContentInsetsRelative(20, 25));
        assertEquals(25, mMainToolbar.getCurrentContentInsetLeft());
        assertEquals(20, mMainToolbar.getCurrentContentInsetStart());
        assertEquals(20, mMainToolbar.getCurrentContentInsetRight());
        assertEquals(25, mMainToolbar.getCurrentContentInsetEnd());

        mActivityRule.runOnUiThread(() -> mMainToolbar.setContentInsetStartWithNavigation(50));
        assertEquals(50, mMainToolbar.getContentInsetStartWithNavigation());
        // Since we haven't configured the navigation icon itself, the current content insets
        // should stay the same
        assertEquals(25, mMainToolbar.getCurrentContentInsetLeft());
        assertEquals(20, mMainToolbar.getCurrentContentInsetStart());
        assertEquals(20, mMainToolbar.getCurrentContentInsetRight());
        assertEquals(25, mMainToolbar.getCurrentContentInsetEnd());

        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.setNavigationIcon(R.drawable.icon_green));
        assertEquals(50, mMainToolbar.getContentInsetStartWithNavigation());
        // Since we have configured the navigation icon, and the currently set start inset with
        // navigation is bigger than currently set start content inset, we should be getting that
        // bigger value now
        assertEquals(25, mMainToolbar.getCurrentContentInsetLeft());
        assertEquals(50, mMainToolbar.getCurrentContentInsetStart());
        assertEquals(50, mMainToolbar.getCurrentContentInsetRight());
        assertEquals(25, mMainToolbar.getCurrentContentInsetEnd());

        mActivityRule.runOnUiThread(() -> mMainToolbar.setContentInsetEndWithActions(35));
        assertEquals(35, mMainToolbar.getContentInsetEndWithActions());
        // Since we haven't configured the menu content, the current content insets
        // should stay the same
        assertEquals(25, mMainToolbar.getCurrentContentInsetLeft());
        assertEquals(50, mMainToolbar.getCurrentContentInsetStart());
        assertEquals(50, mMainToolbar.getCurrentContentInsetRight());
        assertEquals(25, mMainToolbar.getCurrentContentInsetEnd());

        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.inflateMenu(R.menu.toolbar_menu));
        assertEquals(35, mMainToolbar.getContentInsetEndWithActions());
        // Since we have configured the menu content, and the currently set start inset with
        // navigation is bigger than currently set end content inset, we should be getting that
        // bigger value now
        assertEquals(35, mMainToolbar.getCurrentContentInsetLeft());
        assertEquals(50, mMainToolbar.getCurrentContentInsetStart());
        assertEquals(50, mMainToolbar.getCurrentContentInsetRight());
        assertEquals(35, mMainToolbar.getCurrentContentInsetEnd());
    }

    @UiThreadTest
    @Test
    public void testPopupTheme() {
        mMainToolbar.setPopupTheme(R.style.ToolbarPopupTheme_Test);
        assertEquals(R.style.ToolbarPopupTheme_Test, mMainToolbar.getPopupTheme());
    }

    @UiThreadTest
    @Test
    public void testNavigationOnClickListener() {
        View.OnClickListener mockListener = mock(View.OnClickListener.class);
        mMainToolbar.setNavigationOnClickListener(mockListener);

        verify(mockListener, never()).onClick(any(View.class));

        mMainToolbar.getNavigationView().performClick();
        verify(mockListener, times(1)).onClick(any(View.class));

        verifyNoMoreInteractions(mockListener);
    }

    @Test
    public void testItemViewAttributes() throws Throwable {
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.inflateMenu(R.menu.toolbar_menu));

        Menu menu = mMainToolbar.getMenu();

        MenuItem menuItem1 = menu.findItem(R.id.action_highlight);
        assertNotNull(menuItem1.getContentDescription());
        assertNotNull(menuItem1.getTooltipText());

        View itemView1 = mActivity.findViewById(menuItem1.getItemId());
        assertEquals(menuItem1.getContentDescription(), itemView1.getContentDescription());
        assertEquals(menuItem1.getTooltipText(), itemView1.getTooltipText());

        MenuItem menuItem2 = menu.findItem(R.id.action_edit);
        assertNull(menuItem2.getContentDescription());
        assertNull(menuItem2.getTooltipText());

        View itemView2 = mActivity.findViewById(menuItem2.getItemId());
        assertEquals(menuItem2.getTitle(), itemView2.getContentDescription());
        assertEquals(menuItem2.getTitle(), itemView2.getTooltipText());
    }

    @Test
    public void testKeyShortcuts() throws Throwable {
        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar,
                () -> mMainToolbar.inflateMenu(R.menu.toolbar_menu));

        final Boolean[] shareItemClicked = new Boolean[]{false};
        mMainToolbar.getMenu().findItem(R.id.action_share).setOnMenuItemClickListener(
                item -> shareItemClicked[0] = true);

        // Make sure valid menu shortcuts get handled by toolbar menu
        long now = SystemClock.uptimeMillis();
        KeyEvent handledShortcutKey = new KeyEvent(now, now, KeyEvent.ACTION_DOWN,
                KeyEvent.KEYCODE_S, 0, KeyEvent.META_CTRL_ON);
        mInstrumentation.runOnMainSync(() ->
                assertTrue(mActivity.dispatchKeyShortcutEvent(handledShortcutKey))
        );
        assertTrue(shareItemClicked[0]);

        final KeyEvent unhandledShortcutKey = new KeyEvent(now, now, KeyEvent.ACTION_DOWN,
                KeyEvent.KEYCODE_A, 0, KeyEvent.META_CTRL_ON);

        // Make sure we aren't eating unused shortcuts.
        mInstrumentation.runOnMainSync(() ->
                assertFalse(mActivity.dispatchKeyShortcutEvent(unhandledShortcutKey))
        );

        mActivity.resetCounts();

        // Make sure that unhandled shortcuts don't prepare menus (since toolbar is handling that).
        mInstrumentation.sendKeySync(unhandledShortcutKey);
        assertEquals(1, mActivity.mKeyShortcutCount);
        assertEquals(0, mActivity.mPrepareMenuCount);
        assertEquals(0, mActivity.mCreateMenuCount);
    }
}
