blob: b5378d05de55a1e89d1e17e55e129122a6564e71 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.customtabs.dynamicmodule;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.chromium.base.ThreadUtils.runOnUiThreadBlocking;
import android.content.Intent;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.uiautomator.UiDevice;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.chromium.base.ActivityState;
import org.chromium.base.ApplicationStatus;
import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.base.library_loader.LibraryProcessType;
import org.chromium.base.test.util.CallbackHelper;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.DisabledTest;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.AppHooksModule;
import org.chromium.chrome.browser.ChromeFeatureList;
import org.chromium.chrome.browser.ChromeSwitches;
import org.chromium.chrome.browser.customtabs.CustomTabActivity;
import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
import org.chromium.chrome.browser.customtabs.dynamicmodule.CustomTabsDynamicModuleTestUtils.AppHooksModuleForTest;
import org.chromium.chrome.browser.customtabs.dynamicmodule.CustomTabsDynamicModuleTestUtils.IntentBuilder;
import org.chromium.chrome.browser.dependency_injection.ModuleOverridesRule;
import org.chromium.chrome.browser.toolbar.top.CustomTabToolbar;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.util.ChromeTabUtils;
import org.chromium.chrome.test.util.browser.Features;
import org.chromium.content_public.browser.test.util.ClickUtils;
import org.chromium.content_public.browser.test.util.Criteria;
import org.chromium.content_public.browser.test.util.CriteriaHelper;
import org.chromium.content_public.common.ContentSwitches;
import org.chromium.net.test.EmbeddedTestServer;
import org.chromium.net.test.ServerCertificate;
import org.chromium.ui.base.PageTransition;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
/**
* Instrumentation tests for UI elements of {@link CustomTabActivity}
* controlled by a dynamic module.
*/
@RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
// The module managed host is google.com. In test, it is served by the
// EmbeddedTestServer, running on 127.0.0.1, without a valid certificate.
ContentSwitches.HOST_RESOLVER_RULES + "=MAP * 127.0.0.1", "ignore-certificate-errors"})
public class CustomTabsDynamicModuleUITest {
private TestRule mModuleOverridesRule = new ModuleOverridesRule()
.setOverride(AppHooksModule.Factory.class, AppHooksModuleForTest::new);
private CustomTabActivityTestRule mActivityRule = new CustomTabActivityTestRule();
@Rule
public TestRule mOverrideModulesThenLaunchRule =
RuleChain.outerRule(mModuleOverridesRule).around(mActivityRule);
private static final String TEST_PAGE = "/chrome/test/data/android/google.html";
private static final String TEST_PAGE_2 = "/chrome/test/data/android/test.html";
private static final String MODULE_MANAGED_PAGE = "/chrome/test/data/android/about.html";
private static final String MODULE_MANAGED_PAGE_2 = "/chrome/test/data/android/simple.html";
private EmbeddedTestServer mTestServer;
private String mTestPage;
private String mTestPage2;
private String mModuleManagedPage;
private String mModuleManagedPage2;
@Before
public void setUp() throws Exception {
LibraryLoader.getInstance().ensureInitialized(LibraryProcessType.PROCESS_BROWSER);
// Module managed hosts only work with HTTPS.
mTestServer = EmbeddedTestServer.createAndStartHTTPSServer(
InstrumentationRegistry.getInstrumentation().getContext(),
ServerCertificate.CERT_OK);
mTestPage = mTestServer.getURL(TEST_PAGE);
mTestPage2 = mTestServer.getURL(TEST_PAGE_2);
mModuleManagedPage = mTestServer.getURLWithHostName("google.com", MODULE_MANAGED_PAGE);
mModuleManagedPage2 = mTestServer.getURLWithHostName("google.com", MODULE_MANAGED_PAGE_2);
// The embedded test server can't use the 443 port number.
DynamicModuleCoordinator.setAllowNonStandardPortNumber(true);
}
@After
public void tearDown() throws Exception {
DynamicModuleCoordinator.setAllowNonStandardPortNumber(false);
}
/**
* When module is not provided, i.e. module component name is not specified in the intent,
* {@link DynamicModuleCoordinator} is not instantiated, therefore it should not be possible
* to update UI elements of CCT.
*/
@Test
@SmallTest
@Features.EnableFeatures(ChromeFeatureList.CCT_MODULE)
public void testModuleNotProvided() throws InterruptedException {
Intent intent = new IntentBuilder(mModuleManagedPage)
.setModulePackageName(null).setModuleClassName(null)
.setModuleManagedUrlRegex(getModuleManagedRegex())
.build();
mActivityRule.startCustomTabActivityWithIntent(intent);
waitForModuleLoading();
assertFalse(getActivity().getIntentDataProvider().isDynamicModuleEnabled());
assertNoTopBar();
assertCCTHeaderIsVisible();
}
/**
* When feature {@link ChromeFeatureList.CCT_MODULE} is disabled,
* {@link DynamicModuleCoordinator} is not instantiated, therefore it should not be possible
* to update UI elements of CCT.
*/
@Test
@SmallTest
@Features.DisableFeatures(ChromeFeatureList.CCT_MODULE)
public void testFeatureIsDisabled() throws InterruptedException {
Intent intent = new IntentBuilder(mModuleManagedPage)
.setModuleManagedUrlRegex(getModuleManagedRegex())
.build();
mActivityRule.startCustomTabActivityWithIntent(intent);
waitForModuleLoading();
assertFalse(getActivity().getIntentDataProvider().isDynamicModuleEnabled());
assertNoTopBar();
assertCCTHeaderIsVisible();
}
/**
This test executes the following workflow assuming dynamic module has been loaded succesfully:
- moduleManagedUrl1 -> nav1.1 -> nav1.2 -> modulemanagedUrl2 -> nav2.1 -> nav2.2
- User hits the "close button", therefore goes back to modulemanagedUrl2
- User hits the Android back button, going returning to nav1.2
- User hits the "close button" again, going return to moduleManagedUrl1
- User hits the Android back button thereby closes CCT.
*/
@Test
@SmallTest
@DisabledTest
@Features.EnableFeatures(ChromeFeatureList.CCT_MODULE)
public void testCloseButtonBehaviourWithDynamicModule()
throws InterruptedException, ExecutionException, TimeoutException {
Intent intent = new IntentBuilder(mModuleManagedPage)
.setModuleManagedUrlRegex(getModuleManagedRegex())
.build();
// Open CCT with moduleManagedUrl1 and navigate
// moduleManagedUrl1 -> nav1.1 - nav1.2 -> modulemanagedUrl2 -> nav2.1 -> nav2.2
mActivityRule.startCustomTabActivityWithIntent(intent);
CustomTabActivity cctActivity = mActivityRule.getActivity();
mActivityRule.loadUrlInTab(mTestPage, PageTransition.LINK,
cctActivity.getActivityTab());
mActivityRule.loadUrlInTab(mTestPage2, PageTransition.LINK,
cctActivity.getActivityTab());
mActivityRule.loadUrlInTab(mModuleManagedPage2, PageTransition.TYPED,
cctActivity.getActivityTab());
mActivityRule.loadUrlInTab(mTestPage, PageTransition.LINK,
cctActivity.getActivityTab());
mActivityRule.loadUrlInTab(mTestPage2, PageTransition.LINK,
cctActivity.getActivityTab());
// click the close button and wait while tab page loaded
ClickUtils.clickButton(cctActivity.findViewById(R.id.close_button));
ChromeTabUtils.waitForTabPageLoaded(cctActivity.getActivityTab(), null);
// close button returns back to moduleManagedUrl2
assertEquals(mModuleManagedPage2, cctActivity.getActivityTab().getUrl());
// press the back button and wait while tab page loaded
UiDevice mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
mDevice.pressBack();
ChromeTabUtils.waitForTabPageLoaded(cctActivity.getActivityTab(), null);
// the back button returns to nav1.2
assertEquals(mTestPage2, cctActivity.getActivityTab().getUrl());
// click the close button and wait while tab page loaded
ClickUtils.clickButton(cctActivity.findViewById(R.id.close_button));
ChromeTabUtils.waitForTabPageLoaded(cctActivity.getActivityTab(), null);
// close button returns back to moduleManagedUrl1
assertEquals(mModuleManagedPage, cctActivity.getActivityTab().getUrl());
// press back button and while cct is hidden
runAndWaitForActivityStopped(mDevice::pressBack);
}
/**
This test executes the following workflow assuming dynamic module has not been loaded:
- moduleManagedUrl1 -> nav1.1 - nav1.2 -> modulemanagedUrl2 -> nav2.1 -> nav2.2
- User hits the close button, thereby closes CCT
*/
@Test
@SmallTest
public void testCloseButtonBehaviourWithoutDynamicModule()
throws InterruptedException, ExecutionException, TimeoutException {
// Open CCT with moduleManagedUrl1 and navigate
// moduleManagedUrl1 -> nav1.1 - nav1.2 -> modulemanagedUrl2 -> nav2.1 -> nav2.2
Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(
InstrumentationRegistry.getTargetContext(), mModuleManagedPage);
mActivityRule.startCustomTabActivityWithIntent(intent);
CustomTabActivity cctActivity = mActivityRule.getActivity();
mActivityRule.loadUrlInTab(mTestPage, PageTransition.LINK,
cctActivity.getActivityTab());
mActivityRule.loadUrlInTab(mTestPage2, PageTransition.LINK,
cctActivity.getActivityTab());
mActivityRule.loadUrlInTab(mModuleManagedPage2, PageTransition.LINK,
cctActivity.getActivityTab());
mActivityRule.loadUrlInTab(mTestPage, PageTransition.LINK,
cctActivity.getActivityTab());
mActivityRule.loadUrlInTab(mTestPage2, PageTransition.LINK,
cctActivity.getActivityTab());
// click close button and wait while cct is hidden
runAndWaitForActivityStopped(() ->
ClickUtils.clickButton(cctActivity.findViewById(R.id.close_button)));
}
/**
This test executes the following workflow assuming dynamic module loading fails:
- moduleManagedUrl1 -> nav1.1 - nav1.2
- User hits the close button, thereby closes CCT
*/
@Test
@SmallTest
public void testCloseButtonBehaviourDynamicModuleLoadFails()
throws InterruptedException, ExecutionException, TimeoutException {
// Open CCT with moduleManagedUrl1 and navigate
// moduleManagedUrl1 -> nav1.1 - nav1.2
Intent intent = new IntentBuilder(mModuleManagedPage)
.setModuleFailToLoadComponentName()
.setModuleManagedUrlRegex(getModuleManagedRegex()).build();
mActivityRule.startCustomTabActivityWithIntent(intent);
CustomTabActivity cctActivity = mActivityRule.getActivity();
waitForModuleLoading();
mActivityRule.loadUrlInTab(mTestPage, PageTransition.LINK,
cctActivity.getActivityTab());
mActivityRule.loadUrlInTab(mTestPage2, PageTransition.LINK,
cctActivity.getActivityTab());
// click close button and wait while cct is hidden
runAndWaitForActivityStopped(() ->
ClickUtils.clickButton(cctActivity.findViewById(R.id.close_button)));
}
@Test
@SmallTest
@Features.EnableFeatures(ChromeFeatureList.CCT_MODULE)
public void testSetTopBarContentView() throws Exception {
Intent intent = new IntentBuilder(mModuleManagedPage)
.build();
mActivityRule.startCustomTabActivityWithIntent(intent);
waitForModuleLoading();
runOnUiThreadBlocking(() -> {
CustomTabActivity cctActivity = getActivity();
View anyView = new View(cctActivity);
getModuleCoordinator().setTopBarContentView(anyView);
ViewGroup topBar = cctActivity.findViewById(R.id.topbar);
Assert.assertNotNull(topBar);
Assert.assertThat(anyView.getParent(), equalTo(topBar));
assertEquals(View.GONE, anyView.getVisibility());
});
}
@Test
@SmallTest
@Features.EnableFeatures(ChromeFeatureList.CCT_MODULE)
public void testSetTopBarContentView_secondCallIsNoOp() throws Exception {
Intent intent = new IntentBuilder(mModuleManagedPage)
.setModuleManagedUrlRegex(getModuleManagedRegex())
.build();
mActivityRule.startCustomTabActivityWithIntent(intent);
waitForModuleLoading();
DynamicModuleCoordinator coordinator = getModuleCoordinator();
runOnUiThreadBlocking(() -> {
View anyView = new View(getActivity());
coordinator.setTopBarContentView(anyView);
// Second call will not crash.
coordinator.setTopBarContentView(anyView);
});
}
@Test
@SmallTest
@Features.EnableFeatures(ChromeFeatureList.CCT_MODULE)
public void testSetTopBarContentView_moduleLoadingFailed_cctHeaderVisible() throws Exception {
Intent intent = new IntentBuilder(mTestPage).setModuleFailToLoadComponentName().build();
mActivityRule.startCustomTabActivityWithIntent(intent);
waitForModuleLoading();
runOnUiThreadBlocking(() -> {
View anyView = new View(getActivity());
getModuleCoordinator().setTopBarContentView(anyView);
ViewGroup topBar = getActivity().findViewById(R.id.topbar);
Assert.assertNotNull(topBar);
Assert.assertThat(anyView.getParent(), equalTo(topBar));
assertEquals(View.GONE, anyView.getVisibility());
});
assertCCTHeaderIsVisible();
}
@Test
@SmallTest
@Features.EnableFeatures(ChromeFeatureList.CCT_MODULE)
public void testSetTopBarContentView_withModuleAndManagedUrls_topBarVisible() throws Exception {
Intent intent = new IntentBuilder(mModuleManagedPage)
.setModuleManagedUrlRegex(getModuleManagedRegex())
.build();
mActivityRule.startCustomTabActivityWithIntent(intent);
waitForModuleLoading();
runOnUiThreadBlocking(() -> {
CustomTabActivity cctActivity = getActivity();
View anyView = new View(cctActivity);
getModuleCoordinator().setTopBarContentView(anyView);
ViewGroup topBar = cctActivity.findViewById(R.id.topbar);
Assert.assertNotNull(topBar);
Assert.assertThat(anyView.getParent(), equalTo(topBar));
assertEquals(View.VISIBLE, anyView.getVisibility());
});
}
@Test
@SmallTest
@Features.EnableFeatures({
ChromeFeatureList.CCT_MODULE, ChromeFeatureList.CCT_MODULE_CUSTOM_HEADER,
ChromeFeatureList.CCT_MODULE_USE_INTENT_EXTRAS})
public void testSetTopBarContentView_notModuleManagedHost_cctHeaderVisible() throws Exception {
String url = mTestServer.getURLWithHostName("non-managed-domain", MODULE_MANAGED_PAGE);
Intent intent = new IntentBuilder(url)
.setModuleManagedUrlRegex(getModuleManagedRegex())
.setHideCCTHeader(true)
.build();
mActivityRule.startCustomTabActivityWithIntent(intent);
waitForModuleLoading();
runOnUiThreadBlocking(
() -> getModuleCoordinator().setTopBarContentView(new View(getActivity())));
assertCCTHeaderIsVisible();
}
@Test
@SmallTest
@Features.EnableFeatures({
ChromeFeatureList.CCT_MODULE, ChromeFeatureList.CCT_MODULE_CUSTOM_HEADER,
ChromeFeatureList.CCT_MODULE_USE_INTENT_EXTRAS})
public void testSetTopBarContentView_withModuleAndExtras_cctHeaderHidden() throws Exception {
Intent intent = new IntentBuilder(mModuleManagedPage)
.setModuleManagedUrlRegex(getModuleManagedRegex())
.setHideCCTHeader(true)
.build();
mActivityRule.startCustomTabActivityWithIntent(intent);
waitForModuleLoading();
CustomTabActivity cctActivity = getActivity();
runOnUiThreadBlocking(() -> {
getModuleCoordinator().setTopBarContentView(new View(cctActivity));
ViewGroup toolbarContainerView = cctActivity.findViewById(R.id.toolbar_container);
for (int index = 0; index < toolbarContainerView.getChildCount(); index++) {
View childView = toolbarContainerView.getChildAt(index);
if (childView.getId() != R.id.topbar) {
assertEquals(View.GONE, childView.getVisibility());
}
}
});
}
@Test
@SmallTest
@Features.EnableFeatures(ChromeFeatureList.CCT_MODULE_USE_INTENT_EXTRAS)
@Features.DisableFeatures(ChromeFeatureList.CCT_MODULE_CUSTOM_HEADER)
public void testSetTopBarHeight_featureDisabled_heightNotChanged() throws Exception {
Intent intent = new IntentBuilder(mModuleManagedPage)
.setModuleManagedUrlRegex(getModuleManagedRegex())
.setHideCCTHeader(true)
.build();
mActivityRule.startCustomTabActivityWithIntent(intent);
runOnUiThreadBlocking(() -> {
CustomTabActivity cctActivity = getActivity();
int defaultHeight = cctActivity.getFullscreenManager().getTopControlsHeight();
int newHeight = defaultHeight + 10;
getModuleCoordinator().setTopBarHeight(newHeight);
assertEquals(
defaultHeight, cctActivity.getFullscreenManager().getTopControlsHeight());
});
}
@Test
@SmallTest
@Features.EnableFeatures({
ChromeFeatureList.CCT_MODULE, ChromeFeatureList.CCT_MODULE_CUSTOM_HEADER,
ChromeFeatureList.CCT_MODULE_USE_INTENT_EXTRAS})
public void testSetTopBarHeight_cctHeaderNotHidden_heightNotChanged() throws Exception {
Intent intent = new IntentBuilder(mModuleManagedPage)
.setModuleManagedUrlRegex(getModuleManagedRegex())
.setHideCCTHeader(false)
.build();
mActivityRule.startCustomTabActivityWithIntent(intent);
runOnUiThreadBlocking(() -> {
CustomTabActivity cctActivity = getActivity();
int defaultHeight = cctActivity.getFullscreenManager().getTopControlsHeight();
int newHeight = defaultHeight + 10;
getModuleCoordinator().setTopBarHeight(newHeight);
assertEquals(defaultHeight, cctActivity.getFullscreenManager().getTopControlsHeight());
});
}
@Test
@SmallTest
@Features.EnableFeatures({
ChromeFeatureList.CCT_MODULE, ChromeFeatureList.CCT_MODULE_CUSTOM_HEADER,
ChromeFeatureList.CCT_MODULE_USE_INTENT_EXTRAS})
public void testSetTopBarHeight_withModuleAndExtras_heightUpdated() throws Exception {
Intent intent = new IntentBuilder(mModuleManagedPage)
.setModuleManagedUrlRegex(getModuleManagedRegex())
.setHideCCTHeader(true)
.build();
mActivityRule.startCustomTabActivityWithIntent(intent);
runOnUiThreadBlocking(() -> {
CustomTabActivity cctActivity = getActivity();
int defaultHeight = cctActivity.getFullscreenManager().getTopControlsHeight();
int newHeight = defaultHeight + 10;
getModuleCoordinator().setTopBarHeight(newHeight);
assertEquals(newHeight, cctActivity.getFullscreenManager().getTopControlsHeight());
});
}
@Test
@SmallTest
@Features.EnableFeatures({
ChromeFeatureList.CCT_MODULE, ChromeFeatureList.CCT_MODULE_CUSTOM_HEADER,
ChromeFeatureList.CCT_MODULE_USE_INTENT_EXTRAS})
public void testSetTopBarHeight_zeroHeightHidesTopBar() throws Exception {
Intent intent = new IntentBuilder(mModuleManagedPage)
.setModuleManagedUrlRegex(getModuleManagedRegex())
.build();
mActivityRule.startCustomTabActivityWithIntent(intent);
waitForModuleLoading();
runOnUiThreadBlocking(() -> {
CustomTabActivity cctActivity = getActivity();
View anyView = new View(cctActivity);
getModuleCoordinator().setTopBarContentView(anyView);
getModuleCoordinator().setTopBarHeight(0);
assertEquals(View.GONE, anyView.getVisibility());
});
}
@Test
@SmallTest
@Features.EnableFeatures(ChromeFeatureList.CCT_MODULE_USE_INTENT_EXTRAS)
@Features.DisableFeatures(ChromeFeatureList.CCT_MODULE_CUSTOM_HEADER)
public void testSetTopBarContentView_featureDisabled_progressBarNoChange() throws Exception {
Intent intent = new IntentBuilder(mModuleManagedPage)
.setModuleManagedUrlRegex(getModuleManagedRegex())
.setHideCCTHeader(true)
.build();
mActivityRule.startCustomTabActivityWithIntent(intent);
runOnUiThreadBlocking(() -> Assert.assertFalse(canChangeProgressBarTopMargin()));
}
@Test
@SmallTest
@Features.
EnableFeatures({ChromeFeatureList.CCT_MODULE, ChromeFeatureList.CCT_MODULE_CUSTOM_HEADER,
ChromeFeatureList.CCT_MODULE_USE_INTENT_EXTRAS})
public void testSetTopBarContentView_cctHeaderNotHidden_progressBarNoChange() throws Exception {
Intent intent = new IntentBuilder(mModuleManagedPage)
.setModuleManagedUrlRegex(getModuleManagedRegex())
.setHideCCTHeader(false)
.build();
mActivityRule.startCustomTabActivityWithIntent(intent);
runOnUiThreadBlocking(() -> Assert.assertFalse(canChangeProgressBarTopMargin()));
}
@Test
@SmallTest
@Features.
EnableFeatures({ChromeFeatureList.CCT_MODULE, ChromeFeatureList.CCT_MODULE_CUSTOM_HEADER,
ChromeFeatureList.CCT_MODULE_USE_INTENT_EXTRAS})
public void testSetTopBarContentView_withModuleAndExtras_progressBarChanged() throws Exception {
Intent intent = new IntentBuilder(mModuleManagedPage)
.setModuleManagedUrlRegex(getModuleManagedRegex())
.setHideCCTHeader(true)
.build();
mActivityRule.startCustomTabActivityWithIntent(intent);
runOnUiThreadBlocking(() -> Assert.assertTrue(canChangeProgressBarTopMargin()));
}
@Test
@SmallTest
public void testToolbarController_doesNotHideCctTopBar_doesNotAcquiredToken() throws Exception {
Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(
InstrumentationRegistry.getTargetContext(), mTestPage);
CustomTabsTestUtils.setHideCctTopBarOnModuleManagedUrls(intent, false);
mActivityRule.startCustomTabActivityWithIntent(intent);
runOnUiThreadBlocking(() -> {
DynamicModuleToolbarController toolbarController =
getActivity().getComponent().resolveDynamicModuleToolbarController();
Assert.assertFalse(toolbarController.hasAcquiredToken());
});
}
@Test
@SmallTest
@Features.DisableFeatures(ChromeFeatureList.CCT_MODULE)
public void testToolbarController_moduleDisabled_acquiredThenReleasedToken() throws Exception {
Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(
InstrumentationRegistry.getTargetContext(), mTestPage);
CustomTabsTestUtils.setHideCctTopBarOnModuleManagedUrls(intent, true);
mActivityRule.startCustomTabActivityWithIntent(intent);
runOnUiThreadBlocking(() -> {
DynamicModuleToolbarController toolbarController =
getActivity().getComponent().resolveDynamicModuleToolbarController();
Assert.assertTrue(toolbarController.hasAcquiredToken());
Assert.assertTrue(toolbarController.hasReleasedToken());
});
}
@Test
@SmallTest
@Features.EnableFeatures(ChromeFeatureList.CCT_MODULE)
public void testToolbarController_hideCctTopBar_acquiredThenReleasedToken() throws Exception {
Intent intent = new IntentBuilder(mModuleManagedPage).build();
CustomTabsTestUtils.setHideCctTopBarOnModuleManagedUrls(intent, true);
mActivityRule.startCustomTabActivityWithIntent(intent);
runOnUiThreadBlocking(() -> {
DynamicModuleToolbarController toolbarController =
getActivity().getComponent().resolveDynamicModuleToolbarController();
Assert.assertTrue(toolbarController.hasAcquiredToken());
Assert.assertTrue(toolbarController.hasReleasedToken());
});
}
private void assertNoTopBar() {
runOnUiThreadBlocking(() -> {
ViewGroup topBar = getActivity().findViewById(R.id.topbar);
Assert.assertNull(topBar);
});
}
private void assertCCTHeaderIsVisible() {
runOnUiThreadBlocking(() -> {
View toolbarView = getActivity().findViewById(R.id.toolbar);
Assert.assertTrue("A custom tab toolbar is never shown",
toolbarView instanceof CustomTabToolbar);
CustomTabToolbar toolbar = (CustomTabToolbar) toolbarView;
assertEquals(View.VISIBLE, toolbar.getVisibility());
});
}
private String getModuleManagedRegex() {
return "^(" + MODULE_MANAGED_PAGE + "|" + MODULE_MANAGED_PAGE_2 + ")$";
}
private void runAndWaitForActivityStopped(Runnable runnable)
throws TimeoutException, InterruptedException {
CallbackHelper cctHiddenCallback = new CallbackHelper();
ApplicationStatus.ActivityStateListener listener = (activity, newState) -> {
if (activity == getActivity() &&
(newState == ActivityState.STOPPED || newState == ActivityState.DESTROYED)) {
cctHiddenCallback.notifyCalled();
}
};
ApplicationStatus.registerStateListenerForAllActivities(listener);
runnable.run();
cctHiddenCallback.waitForCallback("Hide cct", 0);
ApplicationStatus.unregisterActivityStateListener(listener);
}
private void waitForModuleLoading() {
CriteriaHelper.pollUiThread(new Criteria() {
@Override
public boolean isSatisfied() {
if (!getActivity().getIntentDataProvider().isDynamicModuleEnabled()) return true;
DynamicModuleCoordinator module = getModuleCoordinator();
return module != null && !module.isModuleLoading();
}
});
}
private CustomTabActivity getActivity() {
return mActivityRule.getActivity();
}
private DynamicModuleCoordinator getModuleCoordinator() {
return getActivity().getComponent().resolveDynamicModuleCoordinator();
}
private boolean canChangeProgressBarTopMargin() {
CustomTabActivity cctActivity = getActivity();
ViewGroup controlContainerView = cctActivity.findViewById(R.id.control_container);
int progressBarHeight = 0;
for (int index = 0; index < controlContainerView.getChildCount(); index++) {
View childView = controlContainerView.getChildAt(index);
if (childView.getId() != R.id.toolbar_container) {
// Either ToolbarProgressBar or ToolbarProgressBarAnimatingView
progressBarHeight = childView.getHeight();
break;
}
}
Assert.assertNotEquals(progressBarHeight, 0);
View anyView = new View(cctActivity);
getModuleCoordinator().setTopBarContentView(anyView);
int newMargin = anyView.getBottom() - progressBarHeight;
boolean canChange = false;
for (int index = 0; index < controlContainerView.getChildCount(); index++) {
View childView = controlContainerView.getChildAt(index);
if (childView.getId() != R.id.toolbar_container) {
if (((MarginLayoutParams) childView.getLayoutParams()).topMargin != newMargin) {
return false;
} else {
canChange = true;
}
}
}
return canChange;
}
}