1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.widget.cts; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertNotNull; 22 import static org.junit.Assert.assertNull; 23 import static org.junit.Assert.assertTrue; 24 import static org.mockito.Mockito.any; 25 import static org.mockito.Mockito.mock; 26 import static org.mockito.Mockito.never; 27 import static org.mockito.Mockito.times; 28 import static org.mockito.Mockito.verify; 29 import static org.mockito.Mockito.verifyNoMoreInteractions; 30 31 import android.app.Instrumentation; 32 import android.graphics.Color; 33 import android.graphics.drawable.Drawable; 34 import android.os.SystemClock; 35 import android.view.KeyEvent; 36 import android.view.Menu; 37 import android.view.MenuItem; 38 import android.view.View; 39 import android.widget.Toolbar; 40 import android.widget.cts.util.TestUtils; 41 42 import androidx.test.InstrumentationRegistry; 43 import androidx.test.annotation.UiThreadTest; 44 import androidx.test.filters.MediumTest; 45 import androidx.test.rule.ActivityTestRule; 46 import androidx.test.runner.AndroidJUnit4; 47 48 import com.android.compatibility.common.util.PollingCheck; 49 import com.android.compatibility.common.util.WidgetTestUtils; 50 51 import org.junit.Before; 52 import org.junit.Rule; 53 import org.junit.Test; 54 import org.junit.runner.RunWith; 55 56 @MediumTest 57 @RunWith(AndroidJUnit4.class) 58 public class ToolbarTest { 59 private Instrumentation mInstrumentation; 60 private ToolbarCtsActivity mActivity; 61 private Toolbar mMainToolbar; 62 63 @Rule 64 public ActivityTestRule<ToolbarCtsActivity> mActivityRule = 65 new ActivityTestRule<>(ToolbarCtsActivity.class); 66 67 @Before 68 public void setup() { 69 mInstrumentation = InstrumentationRegistry.getInstrumentation(); 70 mActivity = mActivityRule.getActivity(); 71 mMainToolbar = mActivity.getMainToolbar(); 72 } 73 74 @Test 75 public void testConstructor() { 76 new Toolbar(mActivity); 77 78 new Toolbar(mActivity, null); 79 80 new Toolbar(mActivity, null, android.R.attr.toolbarStyle); 81 82 new Toolbar(mActivity, null, 0, android.R.style.Widget_Material_Toolbar); 83 } 84 85 @Test 86 public void testTitleAndSubtitleContent() throws Throwable { 87 // Note that this method is *not* annotated to run on the UI thread, and every 88 // call to setTitle / setSubtitle is wrapped to wait until the next draw pass 89 // of our main toolbar. While this is not strictly necessary to check the result 90 // of getTitle / getSubtitle, this logic follows the path of deferred layout 91 // and invalidation of the TextViews that show the title / subtitle in the Toolbar. 92 93 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 94 () -> mMainToolbar.setTitle(R.string.toolbar_title)); 95 assertEquals(mActivity.getString(R.string.toolbar_title), mMainToolbar.getTitle()); 96 97 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 98 () -> mMainToolbar.setTitle("New title")); 99 assertEquals("New title", mMainToolbar.getTitle()); 100 101 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 102 () -> mMainToolbar.setSubtitle(R.string.toolbar_subtitle)); 103 assertEquals(mActivity.getString(R.string.toolbar_subtitle), mMainToolbar.getSubtitle()); 104 105 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 106 () -> mMainToolbar.setSubtitle("New subtitle")); 107 assertEquals("New subtitle", mMainToolbar.getSubtitle()); 108 } 109 110 @Test 111 public void testTitleAndSubtitleAppearance() throws Throwable { 112 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 113 () -> mMainToolbar.setTitle(R.string.toolbar_title)); 114 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 115 () -> mMainToolbar.setSubtitle(R.string.toolbar_subtitle)); 116 117 // Since there are no APIs to get reference to the underlying implementation of 118 // title and subtitle, here we are testing that calling the relevant APIs doesn't crash 119 120 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 121 () -> mMainToolbar.setTitleTextColor(Color.RED)); 122 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 123 () -> mMainToolbar.setSubtitleTextColor(Color.BLUE)); 124 125 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 126 () -> mMainToolbar.setTitleTextAppearance( 127 mActivity, R.style.TextAppearance_NotColors)); 128 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 129 () -> mMainToolbar.setSubtitleTextAppearance( 130 mActivity, R.style.TextAppearance_WithColor)); 131 } 132 133 @Test 134 public void testMenuContent() throws Throwable { 135 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 136 () -> mMainToolbar.inflateMenu(R.menu.toolbar_menu)); 137 138 final Menu menu = mMainToolbar.getMenu(); 139 140 assertEquals(6, menu.size()); 141 assertEquals(R.id.action_highlight, menu.getItem(0).getItemId()); 142 assertEquals(R.id.action_edit, menu.getItem(1).getItemId()); 143 assertEquals(R.id.action_delete, menu.getItem(2).getItemId()); 144 assertEquals(R.id.action_ignore, menu.getItem(3).getItemId()); 145 assertEquals(R.id.action_share, menu.getItem(4).getItemId()); 146 assertEquals(R.id.action_print, menu.getItem(5).getItemId()); 147 148 assertFalse(mMainToolbar.hasExpandedActionView()); 149 150 Toolbar.OnMenuItemClickListener menuItemClickListener = 151 mock(Toolbar.OnMenuItemClickListener.class); 152 mMainToolbar.setOnMenuItemClickListener(menuItemClickListener); 153 154 menu.performIdentifierAction(R.id.action_highlight, 0); 155 verify(menuItemClickListener, times(1)).onMenuItemClick( 156 menu.findItem(R.id.action_highlight)); 157 158 menu.performIdentifierAction(R.id.action_share, 0); 159 verify(menuItemClickListener, times(1)).onMenuItemClick( 160 menu.findItem(R.id.action_share)); 161 } 162 163 @Test 164 public void testMenuOverflowShowHide() throws Throwable { 165 // Inflate menu and check that we're not showing overflow menu yet 166 mActivityRule.runOnUiThread(() -> mMainToolbar.inflateMenu(R.menu.toolbar_menu)); 167 assertFalse(mMainToolbar.isOverflowMenuShowing()); 168 169 // Ask to show overflow menu and check that it's showing 170 mActivityRule.runOnUiThread(() -> mMainToolbar.showOverflowMenu()); 171 PollingCheck.waitFor(() -> mMainToolbar.isOverflowMenuShowing()); 172 173 // Ask to hide the overflow menu and check that it's not showing 174 mActivityRule.runOnUiThread(() -> mMainToolbar.hideOverflowMenu()); 175 PollingCheck.waitFor(() -> !mMainToolbar.isOverflowMenuShowing()); 176 } 177 178 @Test 179 public void testMenuOverflowSubmenu() throws Throwable { 180 // Inflate menu and check that we're not showing overflow menu yet 181 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 182 () -> mMainToolbar.inflateMenu(R.menu.toolbar_menu)); 183 assertFalse(mMainToolbar.isOverflowMenuShowing()); 184 185 // Ask to show overflow menu and check that it's showing 186 mActivityRule.runOnUiThread(mMainToolbar::showOverflowMenu); 187 PollingCheck.waitFor(() -> mMainToolbar.isOverflowMenuShowing()); 188 189 // Register a mock menu item click listener on the toolbar 190 Toolbar.OnMenuItemClickListener menuItemClickListener = 191 mock(Toolbar.OnMenuItemClickListener.class); 192 mMainToolbar.setOnMenuItemClickListener(menuItemClickListener); 193 194 final Menu menu = mMainToolbar.getMenu(); 195 196 // Ask to "perform" the share action and check that the menu click listener has 197 // been notified 198 mActivityRule.runOnUiThread(() -> menu.performIdentifierAction(R.id.action_share, 0)); 199 verify(menuItemClickListener, times(1)).onMenuItemClick( 200 menu.findItem(R.id.action_share)); 201 202 // Ask to dismiss all the popups and check that we're not showing the overflow menu 203 mActivityRule.runOnUiThread(mMainToolbar::dismissPopupMenus); 204 PollingCheck.waitFor(() -> !mMainToolbar.isOverflowMenuShowing()); 205 } 206 207 @Test 208 public void testMenuOverflowIcon() throws Throwable { 209 // Inflate menu and check that we're not showing overflow menu yet 210 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 211 () -> mMainToolbar.inflateMenu(R.menu.toolbar_menu)); 212 213 final Drawable overflowIcon = mActivity.getDrawable(R.drawable.icon_red); 214 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 215 () -> mMainToolbar.setOverflowIcon(overflowIcon)); 216 217 final Drawable toolbarOverflowIcon = mMainToolbar.getOverflowIcon(); 218 TestUtils.assertAllPixelsOfColor("Overflow icon is red", toolbarOverflowIcon, 219 toolbarOverflowIcon.getIntrinsicWidth(), toolbarOverflowIcon.getIntrinsicHeight(), 220 true, Color.RED, 1, false); 221 } 222 223 @Test 224 public void testActionView() throws Throwable { 225 // Inflate menu and check that we don't have an expanded action view 226 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 227 () -> mMainToolbar.inflateMenu(R.menu.toolbar_menu_search)); 228 assertFalse(mMainToolbar.hasExpandedActionView()); 229 230 // Expand search menu item's action view and verify that main toolbar has an expanded 231 // action view 232 final MenuItem searchMenuItem = mMainToolbar.getMenu().findItem(R.id.action_search); 233 mActivityRule.runOnUiThread(searchMenuItem::expandActionView); 234 PollingCheck.waitFor(() -> 235 searchMenuItem.isActionViewExpanded() && mMainToolbar.hasExpandedActionView()); 236 237 // Collapse search menu item's action view and verify that main toolbar doesn't have an 238 // expanded action view 239 mActivityRule.runOnUiThread(searchMenuItem::collapseActionView); 240 PollingCheck.waitFor(() -> 241 !searchMenuItem.isActionViewExpanded() && !mMainToolbar.hasExpandedActionView()); 242 243 // Expand search menu item's action view again 244 mActivityRule.runOnUiThread(searchMenuItem::expandActionView); 245 PollingCheck.waitFor(() -> 246 searchMenuItem.isActionViewExpanded() && mMainToolbar.hasExpandedActionView()); 247 248 // Now collapse search menu item's action view via toolbar's API and verify that main 249 // toolbar doesn't have an expanded action view 250 mActivityRule.runOnUiThread(mMainToolbar::collapseActionView); 251 PollingCheck.waitFor(() -> 252 !searchMenuItem.isActionViewExpanded() && !mMainToolbar.hasExpandedActionView()); 253 } 254 255 @Test 256 public void testNavigationConfiguration() throws Throwable { 257 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 258 () -> mMainToolbar.setNavigationIcon(R.drawable.icon_green)); 259 Drawable toolbarNavigationIcon = mMainToolbar.getNavigationIcon(); 260 TestUtils.assertAllPixelsOfColor("Navigation icon is green", toolbarNavigationIcon, 261 toolbarNavigationIcon.getIntrinsicWidth(), 262 toolbarNavigationIcon.getIntrinsicHeight(), 263 true, Color.GREEN, 1, false); 264 265 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 266 () -> mMainToolbar.setNavigationIcon(mActivity.getDrawable(R.drawable.icon_blue))); 267 toolbarNavigationIcon = mMainToolbar.getNavigationIcon(); 268 TestUtils.assertAllPixelsOfColor("Navigation icon is blue", toolbarNavigationIcon, 269 toolbarNavigationIcon.getIntrinsicWidth(), 270 toolbarNavigationIcon.getIntrinsicHeight(), 271 true, Color.BLUE, 1, false); 272 273 mActivityRule.runOnUiThread( 274 () -> mMainToolbar.setNavigationContentDescription(R.string.toolbar_navigation)); 275 assertEquals(mActivity.getResources().getString(R.string.toolbar_navigation), 276 mMainToolbar.getNavigationContentDescription()); 277 278 mActivityRule.runOnUiThread( 279 () -> mMainToolbar.setNavigationContentDescription("Navigation legend")); 280 assertEquals("Navigation legend", mMainToolbar.getNavigationContentDescription()); 281 } 282 283 @Test 284 public void testCollapseConfiguration() throws Throwable { 285 // Inflate menu and expand action view to display collapse button 286 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 287 () -> mMainToolbar.inflateMenu(R.menu.toolbar_menu_search)); 288 final MenuItem searchMenuItem = mMainToolbar.getMenu().findItem(R.id.action_search); 289 mActivityRule.runOnUiThread(searchMenuItem::expandActionView); 290 PollingCheck.waitFor(() -> 291 searchMenuItem.isActionViewExpanded() && mMainToolbar.hasExpandedActionView()); 292 293 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 294 () -> mMainToolbar.setCollapseIcon(R.drawable.icon_green)); 295 Drawable toolbarCollapseIcon = mMainToolbar.getCollapseIcon(); 296 TestUtils.assertAllPixelsOfColor("Collapse icon is green", toolbarCollapseIcon, 297 toolbarCollapseIcon.getIntrinsicWidth(), 298 toolbarCollapseIcon.getIntrinsicHeight(), 299 true, Color.GREEN, 1, false); 300 301 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 302 () -> mMainToolbar.setCollapseIcon(mActivity.getDrawable(R.drawable.icon_blue))); 303 toolbarCollapseIcon = mMainToolbar.getCollapseIcon(); 304 TestUtils.assertAllPixelsOfColor("Collapse icon is blue", toolbarCollapseIcon, 305 toolbarCollapseIcon.getIntrinsicWidth(), 306 toolbarCollapseIcon.getIntrinsicHeight(), 307 true, Color.BLUE, 1, false); 308 309 mActivityRule.runOnUiThread( 310 () -> mMainToolbar.setCollapseContentDescription(R.string.toolbar_collapse)); 311 assertEquals(mActivity.getResources().getString(R.string.toolbar_collapse), 312 mMainToolbar.getCollapseContentDescription()); 313 314 mActivityRule.runOnUiThread( 315 () -> mMainToolbar.setCollapseContentDescription("Collapse legend")); 316 assertEquals("Collapse legend", mMainToolbar.getCollapseContentDescription()); 317 } 318 319 @Test 320 public void testLogoConfiguration() throws Throwable { 321 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 322 () -> mMainToolbar.setLogo(R.drawable.icon_yellow)); 323 Drawable toolbarLogo = mMainToolbar.getLogo(); 324 TestUtils.assertAllPixelsOfColor("Logo is yellow", toolbarLogo, 325 toolbarLogo.getIntrinsicWidth(), 326 toolbarLogo.getIntrinsicHeight(), 327 true, Color.YELLOW, 1, false); 328 329 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 330 () -> mMainToolbar.setLogo(mActivity.getDrawable(R.drawable.icon_red))); 331 toolbarLogo = mMainToolbar.getLogo(); 332 TestUtils.assertAllPixelsOfColor("Logo is red", toolbarLogo, 333 toolbarLogo.getIntrinsicWidth(), 334 toolbarLogo.getIntrinsicHeight(), 335 true, Color.RED, 1, false); 336 337 mActivityRule.runOnUiThread( 338 () -> mMainToolbar.setLogoDescription(R.string.toolbar_logo)); 339 assertEquals(mActivity.getResources().getString(R.string.toolbar_logo), 340 mMainToolbar.getLogoDescription()); 341 342 mActivityRule.runOnUiThread( 343 () -> mMainToolbar.setLogoDescription("Logo legend")); 344 assertEquals("Logo legend", mMainToolbar.getLogoDescription()); 345 } 346 347 @UiThreadTest 348 @Test 349 public void testContentInsetsLtr() { 350 mMainToolbar.setLayoutDirection(View.LAYOUT_DIRECTION_LTR); 351 352 mMainToolbar.setContentInsetsAbsolute(20, 25); 353 assertEquals(20, mMainToolbar.getContentInsetLeft()); 354 assertEquals(20, mMainToolbar.getContentInsetStart()); 355 assertEquals(25, mMainToolbar.getContentInsetRight()); 356 assertEquals(25, mMainToolbar.getContentInsetEnd()); 357 358 mMainToolbar.setContentInsetsRelative(40, 20); 359 assertEquals(40, mMainToolbar.getContentInsetLeft()); 360 assertEquals(40, mMainToolbar.getContentInsetStart()); 361 assertEquals(20, mMainToolbar.getContentInsetRight()); 362 assertEquals(20, mMainToolbar.getContentInsetEnd()); 363 } 364 365 @UiThreadTest 366 @Test 367 public void testContentInsetsRtl() { 368 mMainToolbar.setLayoutDirection(View.LAYOUT_DIRECTION_RTL); 369 370 mMainToolbar.setContentInsetsAbsolute(20, 25); 371 assertEquals(20, mMainToolbar.getContentInsetLeft()); 372 assertEquals(25, mMainToolbar.getContentInsetStart()); 373 assertEquals(25, mMainToolbar.getContentInsetRight()); 374 assertEquals(20, mMainToolbar.getContentInsetEnd()); 375 376 mMainToolbar.setContentInsetsRelative(40, 20); 377 assertEquals(20, mMainToolbar.getContentInsetLeft()); 378 assertEquals(40, mMainToolbar.getContentInsetStart()); 379 assertEquals(40, mMainToolbar.getContentInsetRight()); 380 assertEquals(20, mMainToolbar.getContentInsetEnd()); 381 } 382 383 @Test 384 public void testCurrentContentInsetsLtr() throws Throwable { 385 mActivityRule.runOnUiThread( 386 () -> mMainToolbar.setLayoutDirection(View.LAYOUT_DIRECTION_LTR)); 387 388 mActivityRule.runOnUiThread(() -> mMainToolbar.setContentInsetsRelative(20, 25)); 389 assertEquals(20, mMainToolbar.getCurrentContentInsetLeft()); 390 assertEquals(20, mMainToolbar.getCurrentContentInsetStart()); 391 assertEquals(25, mMainToolbar.getCurrentContentInsetRight()); 392 assertEquals(25, mMainToolbar.getCurrentContentInsetEnd()); 393 394 mActivityRule.runOnUiThread(() -> mMainToolbar.setContentInsetStartWithNavigation(50)); 395 assertEquals(50, mMainToolbar.getContentInsetStartWithNavigation()); 396 // Since we haven't configured the navigation icon itself, the current content insets 397 // should stay the same 398 assertEquals(20, mMainToolbar.getCurrentContentInsetLeft()); 399 assertEquals(20, mMainToolbar.getCurrentContentInsetStart()); 400 assertEquals(25, mMainToolbar.getCurrentContentInsetRight()); 401 assertEquals(25, mMainToolbar.getCurrentContentInsetEnd()); 402 403 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 404 () -> mMainToolbar.setNavigationIcon(R.drawable.icon_green)); 405 assertEquals(50, mMainToolbar.getContentInsetStartWithNavigation()); 406 // Since we have configured the navigation icon, and the currently set start inset with 407 // navigation is bigger than currently set start content inset, we should be getting that 408 // bigger value now 409 assertEquals(50, mMainToolbar.getCurrentContentInsetLeft()); 410 assertEquals(50, mMainToolbar.getCurrentContentInsetStart()); 411 assertEquals(25, mMainToolbar.getCurrentContentInsetRight()); 412 assertEquals(25, mMainToolbar.getCurrentContentInsetEnd()); 413 414 mActivityRule.runOnUiThread(() -> mMainToolbar.setContentInsetEndWithActions(35)); 415 assertEquals(35, mMainToolbar.getContentInsetEndWithActions()); 416 // Since we haven't configured the menu content, the current content insets 417 // should stay the same 418 assertEquals(50, mMainToolbar.getCurrentContentInsetLeft()); 419 assertEquals(50, mMainToolbar.getCurrentContentInsetStart()); 420 assertEquals(25, mMainToolbar.getCurrentContentInsetRight()); 421 assertEquals(25, mMainToolbar.getCurrentContentInsetEnd()); 422 423 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 424 () -> mMainToolbar.inflateMenu(R.menu.toolbar_menu)); 425 assertEquals(35, mMainToolbar.getContentInsetEndWithActions()); 426 // Since we have configured the menu content, and the currently set start inset with 427 // navigation is bigger than currently set end content inset, we should be getting that 428 // bigger value now 429 assertEquals(50, mMainToolbar.getCurrentContentInsetLeft()); 430 assertEquals(50, mMainToolbar.getCurrentContentInsetStart()); 431 assertEquals(35, mMainToolbar.getCurrentContentInsetRight()); 432 assertEquals(35, mMainToolbar.getCurrentContentInsetEnd()); 433 } 434 435 @Test 436 public void testCurrentContentInsetsRtl() throws Throwable { 437 mActivityRule.runOnUiThread( 438 () -> mMainToolbar.setLayoutDirection(View.LAYOUT_DIRECTION_RTL)); 439 440 mActivityRule.runOnUiThread(() -> mMainToolbar.setContentInsetsRelative(20, 25)); 441 assertEquals(25, mMainToolbar.getCurrentContentInsetLeft()); 442 assertEquals(20, mMainToolbar.getCurrentContentInsetStart()); 443 assertEquals(20, mMainToolbar.getCurrentContentInsetRight()); 444 assertEquals(25, mMainToolbar.getCurrentContentInsetEnd()); 445 446 mActivityRule.runOnUiThread(() -> mMainToolbar.setContentInsetStartWithNavigation(50)); 447 assertEquals(50, mMainToolbar.getContentInsetStartWithNavigation()); 448 // Since we haven't configured the navigation icon itself, the current content insets 449 // should stay the same 450 assertEquals(25, mMainToolbar.getCurrentContentInsetLeft()); 451 assertEquals(20, mMainToolbar.getCurrentContentInsetStart()); 452 assertEquals(20, mMainToolbar.getCurrentContentInsetRight()); 453 assertEquals(25, mMainToolbar.getCurrentContentInsetEnd()); 454 455 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 456 () -> mMainToolbar.setNavigationIcon(R.drawable.icon_green)); 457 assertEquals(50, mMainToolbar.getContentInsetStartWithNavigation()); 458 // Since we have configured the navigation icon, and the currently set start inset with 459 // navigation is bigger than currently set start content inset, we should be getting that 460 // bigger value now 461 assertEquals(25, mMainToolbar.getCurrentContentInsetLeft()); 462 assertEquals(50, mMainToolbar.getCurrentContentInsetStart()); 463 assertEquals(50, mMainToolbar.getCurrentContentInsetRight()); 464 assertEquals(25, mMainToolbar.getCurrentContentInsetEnd()); 465 466 mActivityRule.runOnUiThread(() -> mMainToolbar.setContentInsetEndWithActions(35)); 467 assertEquals(35, mMainToolbar.getContentInsetEndWithActions()); 468 // Since we haven't configured the menu content, the current content insets 469 // should stay the same 470 assertEquals(25, mMainToolbar.getCurrentContentInsetLeft()); 471 assertEquals(50, mMainToolbar.getCurrentContentInsetStart()); 472 assertEquals(50, mMainToolbar.getCurrentContentInsetRight()); 473 assertEquals(25, mMainToolbar.getCurrentContentInsetEnd()); 474 475 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 476 () -> mMainToolbar.inflateMenu(R.menu.toolbar_menu)); 477 assertEquals(35, mMainToolbar.getContentInsetEndWithActions()); 478 // Since we have configured the menu content, and the currently set start inset with 479 // navigation is bigger than currently set end content inset, we should be getting that 480 // bigger value now 481 assertEquals(35, mMainToolbar.getCurrentContentInsetLeft()); 482 assertEquals(50, mMainToolbar.getCurrentContentInsetStart()); 483 assertEquals(50, mMainToolbar.getCurrentContentInsetRight()); 484 assertEquals(35, mMainToolbar.getCurrentContentInsetEnd()); 485 } 486 487 @UiThreadTest 488 @Test 489 public void testPopupTheme() { 490 mMainToolbar.setPopupTheme(R.style.ToolbarPopupTheme_Test); 491 assertEquals(R.style.ToolbarPopupTheme_Test, mMainToolbar.getPopupTheme()); 492 } 493 494 @UiThreadTest 495 @Test 496 public void testNavigationOnClickListener() { 497 View.OnClickListener mockListener = mock(View.OnClickListener.class); 498 mMainToolbar.setNavigationOnClickListener(mockListener); 499 500 verify(mockListener, never()).onClick(any(View.class)); 501 502 mMainToolbar.getNavigationView().performClick(); 503 verify(mockListener, times(1)).onClick(any(View.class)); 504 505 verifyNoMoreInteractions(mockListener); 506 } 507 508 @Test 509 public void testItemViewAttributes() throws Throwable { 510 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 511 () -> mMainToolbar.inflateMenu(R.menu.toolbar_menu)); 512 513 Menu menu = mMainToolbar.getMenu(); 514 515 MenuItem menuItem1 = menu.findItem(R.id.action_highlight); 516 assertNotNull(menuItem1.getContentDescription()); 517 assertNotNull(menuItem1.getTooltipText()); 518 519 View itemView1 = mActivity.findViewById(menuItem1.getItemId()); 520 assertEquals(menuItem1.getContentDescription(), itemView1.getContentDescription()); 521 assertEquals(menuItem1.getTooltipText(), itemView1.getTooltipText()); 522 523 MenuItem menuItem2 = menu.findItem(R.id.action_edit); 524 assertNull(menuItem2.getContentDescription()); 525 assertNull(menuItem2.getTooltipText()); 526 527 View itemView2 = mActivity.findViewById(menuItem2.getItemId()); 528 assertEquals(menuItem2.getTitle(), itemView2.getContentDescription()); 529 assertEquals(menuItem2.getTitle(), itemView2.getTooltipText()); 530 } 531 532 @Test 533 public void testKeyShortcuts() throws Throwable { 534 WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, mMainToolbar, 535 () -> mMainToolbar.inflateMenu(R.menu.toolbar_menu)); 536 537 final Boolean[] shareItemClicked = new Boolean[]{false}; 538 mMainToolbar.getMenu().findItem(R.id.action_share).setOnMenuItemClickListener( 539 item -> shareItemClicked[0] = true); 540 541 // Make sure valid menu shortcuts get handled by toolbar menu 542 long now = SystemClock.uptimeMillis(); 543 KeyEvent handledShortcutKey = new KeyEvent(now, now, KeyEvent.ACTION_DOWN, 544 KeyEvent.KEYCODE_S, 0, KeyEvent.META_CTRL_ON); 545 mInstrumentation.runOnMainSync(() -> 546 assertTrue(mActivity.dispatchKeyShortcutEvent(handledShortcutKey)) 547 ); 548 assertTrue(shareItemClicked[0]); 549 550 final KeyEvent unhandledShortcutKey = new KeyEvent(now, now, KeyEvent.ACTION_DOWN, 551 KeyEvent.KEYCODE_A, 0, KeyEvent.META_CTRL_ON); 552 553 // Make sure we aren't eating unused shortcuts. 554 mInstrumentation.runOnMainSync(() -> 555 assertFalse(mActivity.dispatchKeyShortcutEvent(unhandledShortcutKey)) 556 ); 557 558 mActivity.resetCounts(); 559 560 // Make sure that unhandled shortcuts don't prepare menus (since toolbar is handling that). 561 mInstrumentation.sendKeySync(unhandledShortcutKey); 562 assertEquals(1, mActivity.mKeyShortcutCount); 563 assertEquals(0, mActivity.mPrepareMenuCount); 564 assertEquals(0, mActivity.mCreateMenuCount); 565 } 566 } 567