Commit 2e2b5c64 authored by Peter Kotwicz's avatar Peter Kotwicz Committed by Commit Bot

Merge WebAPK/TWA status bar behaviour 2/3

This CL makes WebappActivity use CustomTabStatusBarColorProvider

BUG=997793
R=peconn, dominickn
TBR=yfriedman
    (for location of ThemeTestUtils.java)

Change-Id: Ie964caea7e7708d88934fcb16d226d7f155203df
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1858605Reviewed-by: default avatarPeter Kotwicz <pkotwicz@chromium.org>
Reviewed-by: default avatarPeter Conn <peconn@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Commit-Queue: Peter Kotwicz <pkotwicz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#718789}
parent ea6b9281
......@@ -6,12 +6,16 @@ package org.chromium.chrome.browser.customtabs;
import android.view.KeyEvent;
import androidx.annotation.VisibleForTesting;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.KeyboardShortcuts;
import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider;
import org.chromium.chrome.browser.customtabs.content.CustomTabActivityNavigationController;
import org.chromium.chrome.browser.customtabs.features.toolbar.CustomTabToolbarCoordinator;
import org.chromium.chrome.browser.dependency_injection.ChromeActivityComponent;
import org.chromium.chrome.browser.tab.TabState;
import org.chromium.chrome.browser.ui.RootUiCoordinator;
/**
......@@ -24,6 +28,7 @@ public abstract class BaseCustomTabActivity<C extends ChromeActivityComponent>
extends ChromeActivity<C> {
protected CustomTabToolbarCoordinator mToolbarCoordinator;
protected CustomTabActivityNavigationController mNavigationController;
protected CustomTabStatusBarColorProvider mStatusBarColorProvider;
// This is to give the right package name while using the client's resources during an
// overridePendingTransition call.
......@@ -31,6 +36,12 @@ public abstract class BaseCustomTabActivity<C extends ChromeActivityComponent>
// change the package name.
protected boolean mShouldOverridePackage;
/**
* @return The {@link BrowserServicesIntentDataProvider} for this {@link CustomTabActivity}.
*/
@VisibleForTesting
public abstract BrowserServicesIntentDataProvider getIntentDataProvider();
@Override
protected RootUiCoordinator createRootUiCoordinator() {
// TODO(https://crbug.com/1020324): Move this logic into a CustomTabRootUICoordinator that
......@@ -69,6 +80,25 @@ public abstract class BaseCustomTabActivity<C extends ChromeActivityComponent>
}
@Override
public int getActivityThemeColor() {
if (getIntentDataProvider().isOpenedByChrome()) {
return TabState.UNSPECIFIED_THEME_COLOR;
}
return getIntentDataProvider().getToolbarColor();
}
@Override
public int getBaseStatusBarColor() {
return mStatusBarColorProvider.getBaseStatusBarColor(super.getBaseStatusBarColor());
}
@Override
public boolean isStatusBarDefaultThemeColor() {
return mStatusBarColorProvider.isStatusBarDefaultThemeColor(
super.isStatusBarDefaultThemeColor());
}
public boolean dispatchKeyEvent(KeyEvent event) {
Boolean result = KeyboardShortcuts.dispatchKeyEvent(
event, this, mToolbarCoordinator.toolbarIsInitialized());
......
......@@ -23,7 +23,6 @@ import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.browser.customtabs.CustomTabsIntent;
import androidx.browser.customtabs.CustomTabsSessionToken;
......@@ -58,7 +57,6 @@ import org.chromium.chrome.browser.night_mode.SystemNightModeMonitor;
import org.chromium.chrome.browser.page_info.PageInfoController;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabImpl;
import org.chromium.chrome.browser.tab.TabState;
import org.chromium.chrome.browser.tabmodel.ChromeTabCreator;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorImpl;
......@@ -77,7 +75,6 @@ public class CustomTabActivity extends BaseCustomTabActivity<CustomTabActivityCo
private CustomTabActivityTabController mTabController;
private CustomTabActivityTabProvider mTabProvider;
private CustomTabActivityTabFactory mTabFactory;
private CustomTabStatusBarColorProvider mCustomTabStatusBarColorProvider;
private CustomTabIntentHandler mCustomTabIntentHandler;
private final CustomTabsConnection mConnection = CustomTabsConnection.getInstance();
......@@ -116,7 +113,6 @@ public class CustomTabActivity extends BaseCustomTabActivity<CustomTabActivityCo
}
};
@Override
protected Drawable getBackgroundDrawable() {
int initialBackgroundColor = mIntentDataProvider.getInitialBackgroundColor();
......@@ -398,34 +394,10 @@ public class CustomTabActivity extends BaseCustomTabActivity<CustomTabActivityCo
this, getTabModelSelector(), R.id.bookmark_this_page_id, R.id.preferences_id);
}
@Override
public int getActivityThemeColor() {
if (mIntentDataProvider.isOpenedByChrome()) {
return TabState.UNSPECIFIED_THEME_COLOR;
}
return mIntentDataProvider.getToolbarColor();
}
@Override
public int getBaseStatusBarColor() {
return mCustomTabStatusBarColorProvider
.getBaseStatusBarColor(super.getBaseStatusBarColor());
}
@Override
public boolean isStatusBarDefaultThemeColor() {
return mCustomTabStatusBarColorProvider
.isStatusBarDefaultThemeColor(super.isStatusBarDefaultThemeColor());
}
@Override
public void onUpdateStateChanged() {}
/**
* @return The {@link BrowserServicesIntentDataProvider} for this {@link CustomTabActivity}.
*/
@VisibleForTesting
@Override
public BrowserServicesIntentDataProvider getIntentDataProvider() {
return mIntentDataProvider;
}
......@@ -510,7 +482,7 @@ public class CustomTabActivity extends BaseCustomTabActivity<CustomTabActivityCo
ChromeApplication.getComponent().createCustomTabActivityComponent(
commonsModule, customTabsModule);
mCustomTabStatusBarColorProvider = component.resolveCustomTabStatusBarColorProvider();
mStatusBarColorProvider = component.resolveCustomTabStatusBarColorProvider();
mTabController = component.resolveTabController();
mTabProvider = component.resolveTabProvider();
mTabFactory = component.resolveTabFactory();
......
......@@ -9,7 +9,11 @@ import static org.chromium.chrome.browser.ui.system.StatusBarColorController.UND
import org.chromium.chrome.browser.ActivityTabProvider;
import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider;
import org.chromium.chrome.browser.dependency_injection.ActivityScope;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabThemeColorHelper;
import org.chromium.chrome.browser.ui.system.StatusBarColorController;
import org.chromium.chrome.browser.webapps.WebDisplayMode;
import org.chromium.chrome.browser.webapps.WebappExtras;
import javax.inject.Inject;
......@@ -47,12 +51,33 @@ public class CustomTabStatusBarColorProvider {
int getBaseStatusBarColor(int fallbackStatusBarColor) {
if (mIntentDataProvider.isOpenedByChrome()) return fallbackStatusBarColor;
return mActivityTabProvider.get() != null && mUseTabThemeColor
? UNDEFINED_STATUS_BAR_COLOR
Tab tab = mActivityTabProvider.get();
if (tab == null) {
return mIntentDataProvider.getToolbarColor();
}
if (shouldUseDefaultThemeColorForFullscreen()) {
return TabThemeColorHelper.getDefaultColor(tab);
}
return mUseTabThemeColor ? UNDEFINED_STATUS_BAR_COLOR
: mIntentDataProvider.getToolbarColor();
}
boolean isStatusBarDefaultThemeColor(boolean isFallbackColorDefault) {
return mIntentDataProvider.isOpenedByChrome() && isFallbackColorDefault;
if (mIntentDataProvider.isOpenedByChrome()) {
return isFallbackColorDefault;
}
return shouldUseDefaultThemeColorForFullscreen();
}
private boolean shouldUseDefaultThemeColorForFullscreen() {
// Don't use the theme color provided by the page if we're in display: fullscreen. This
// works around an issue where the status bars go transparent and can't be seen on top of
// the page content when users swipe them in or they appear because the on-screen keyboard
// was triggered.
WebappExtras webappExtras = mIntentDataProvider.getWebappExtras();
return (webappExtras != null && webappExtras.displayMode == WebDisplayMode.FULLSCREEN);
}
}
......@@ -9,7 +9,6 @@ import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_M
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.net.Uri;
......@@ -36,6 +35,7 @@ import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.ChromeApplication;
import org.chromium.chrome.browser.IntentHandler;
import org.chromium.chrome.browser.WarmupManager;
import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider;
import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider.CustomTabsUiType;
import org.chromium.chrome.browser.customtabs.BaseCustomTabActivity;
import org.chromium.chrome.browser.customtabs.CustomTabAppMenuPropertiesDelegate;
......@@ -52,11 +52,13 @@ import org.chromium.chrome.browser.tab.TabDelegateFactory;
import org.chromium.chrome.browser.tab.TabImpl;
import org.chromium.chrome.browser.tab.TabObserver;
import org.chromium.chrome.browser.tab.TabState;
import org.chromium.chrome.browser.tab.TabThemeColorHelper;
import org.chromium.chrome.browser.tabmodel.SingleTabModelSelector;
import org.chromium.chrome.browser.tabmodel.TabLaunchType;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.tabmodel.TabSelectionType;
import org.chromium.chrome.browser.ui.appmenu.AppMenuPropertiesDelegate;
import org.chromium.chrome.browser.ui.system.StatusBarColorController;
import org.chromium.chrome.browser.ui.widget.TintedDrawable;
import org.chromium.chrome.browser.usage_stats.UsageStatsService;
import org.chromium.chrome.browser.util.AndroidTaskUtils;
......@@ -92,6 +94,7 @@ public class WebappActivity extends BaseCustomTabActivity<WebappActivityComponen
private WebappInfo mWebappInfo;
private BrowserServicesIntentDataProvider mIntentDataProvider;
private WebappActivityTabController mTabController;
private SplashController mSplashController;
private TabObserverRegistrar mTabObserverRegistrar;
......@@ -157,6 +160,11 @@ public class WebappActivity extends BaseCustomTabActivity<WebappActivityComponen
mDisclosureSnackbarController = new WebappDisclosureSnackbarController();
}
@Override
public BrowserServicesIntentDataProvider getIntentDataProvider() {
return mIntentDataProvider;
}
@Override
protected void onNewIntent(Intent intent) {
if (intent == null) return;
......@@ -346,7 +354,8 @@ public class WebappActivity extends BaseCustomTabActivity<WebappActivityComponen
@Override
protected WebappActivityComponent createComponent(ChromeActivityCommonsModule commonsModule) {
WebappActivityModule webappModule = new WebappActivityModule(mWebappInfo.getProvider());
mIntentDataProvider = mWebappInfo.getProvider();
WebappActivityModule webappModule = new WebappActivityModule(mIntentDataProvider);
WebappActivityComponent component =
ChromeApplication.getComponent().createWebappActivityComponent(
commonsModule, webappModule);
......@@ -354,6 +363,9 @@ public class WebappActivity extends BaseCustomTabActivity<WebappActivityComponen
mToolbarCoordinator = component.resolveToolbarCoordinator();
mNavigationController = component.resolveNavigationController();
mStatusBarColorProvider = component.resolveCustomTabStatusBarColorProvider();
mStatusBarColorProvider.setUseTabThemeColor(true /* useTabThemeColor */);
component.resolveCompositorContentInitializer();
mNavigationController.setFinishHandler((reason) -> { handleFinishAndClose(); });
......@@ -661,17 +673,19 @@ public class WebappActivity extends BaseCustomTabActivity<WebappActivityComponen
}
private void updateTaskDescription() {
Tab tab = getActivityTab();
String title = null;
if (!TextUtils.isEmpty(mWebappInfo.shortName())) {
title = mWebappInfo.shortName();
} else if (getActivityTab() != null) {
title = getActivityTab().getTitle();
} else if (tab != null) {
title = tab.getTitle();
}
Bitmap icon = null;
if (mWebappInfo.icon() != null) {
icon = mWebappInfo.icon().bitmap();
} else if (getActivityTab() != null) {
} else if (tab != null) {
icon = mLargestFavicon;
}
......@@ -688,30 +702,19 @@ public class WebappActivity extends BaseCustomTabActivity<WebappActivityComponen
// triggered.
if (mBrandColor != null && mWebappInfo.displayMode() != WebDisplayMode.FULLSCREEN) {
taskDescriptionColor = mBrandColor;
if (getToolbarManager() != null) {
getToolbarManager().onThemeColorChanged(mBrandColor, false);
}
}
ApiCompatibilityUtils.setTaskDescription(this, title, icon,
ColorUtils.getOpaqueColor(taskDescriptionColor));
getStatusBarColorController().updateStatusBarColor(isStatusBarDefaultThemeColor());
}
@Override
public int getBaseStatusBarColor() {
// White default color is used to match CCTs and WebAPK shell. The returned color is ignored
// pre Android M when isStatusBarDefaultThemeColor() == true.
return isStatusBarDefaultThemeColor() ? Color.WHITE : mBrandColor;
if (getToolbarManager() != null && !isStatusBarDefaultThemeColor()) {
int toolbarColor = getBaseStatusBarColor();
if (toolbarColor == StatusBarColorController.UNDEFINED_STATUS_BAR_COLOR) {
toolbarColor = (tab == null) ? mIntentDataProvider.getToolbarColor()
: TabThemeColorHelper.getColor(tab);
}
getToolbarManager().onThemeColorChanged(toolbarColor, false);
}
@Override
public boolean isStatusBarDefaultThemeColor() {
// Don't use the brand color for the status bars if we're in display: fullscreen. This works
// around an issue where the status bars go transparent and can't be seen on top of the page
// content when users swipe them in or they appear because the on-screen keyboard was
// triggered.
return mBrandColor == null || mWebappInfo.displayMode() == WebDisplayMode.FULLSCREEN;
}
@Override
......
......@@ -5,6 +5,7 @@
package org.chromium.chrome.browser.webapps.dependency_injection;
import org.chromium.chrome.browser.customtabs.CustomTabCompositorContentInitializer;
import org.chromium.chrome.browser.customtabs.CustomTabStatusBarColorProvider;
import org.chromium.chrome.browser.customtabs.content.CustomTabActivityNavigationController;
import org.chromium.chrome.browser.customtabs.content.TabObserverRegistrar;
import org.chromium.chrome.browser.customtabs.features.toolbar.CustomTabToolbarCoordinator;
......@@ -25,6 +26,7 @@ import dagger.Subcomponent;
public interface WebappActivityComponent extends ChromeActivityComponent {
CustomTabActivityNavigationController resolveNavigationController();
CustomTabCompositorContentInitializer resolveCompositorContentInitializer();
CustomTabStatusBarColorProvider resolveCustomTabStatusBarColorProvider();
CustomTabToolbarCoordinator resolveToolbarCoordinator();
SplashController resolveSplashController();
TabObserverRegistrar resolveTabObserverRegistrar();
......
......@@ -4,7 +4,6 @@
package org.chromium.chrome.browser.browserservices;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
......@@ -33,20 +32,18 @@ import org.chromium.base.CommandLine;
import org.chromium.base.ContextUtils;
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.MinAndroidSdkLevel;
import org.chromium.base.test.util.Restriction;
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.tab.EmptyTabObserver;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabBrowserControlsState;
import org.chromium.chrome.browser.tab.TabThemeColorHelper;
import org.chromium.chrome.browser.util.ColorUtils;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.util.ChromeTabUtils;
import org.chromium.chrome.test.util.browser.ThemeTestUtils;
import org.chromium.content_public.browser.test.util.Criteria;
import org.chromium.content_public.browser.test.util.CriteriaHelper;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
......@@ -56,7 +53,6 @@ import org.chromium.ui.test.util.UiRestriction;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
......@@ -144,8 +140,8 @@ public class TrustedWebActivityTest {
intent.putExtra(CustomTabsIntent.EXTRA_TOOLBAR_COLOR, Color.GREEN);
launchCustomTabActivity(intent);
CustomTabActivity activity = mCustomTabActivityTestRule.getActivity();
waitForThemeColor(activity, Color.RED);
assertStatusBarColor(activity, Color.RED);
ThemeTestUtils.waitForThemeColor(activity, Color.RED);
ThemeTestUtils.assertStatusBarColor(activity, Color.RED);
}
/**
......@@ -168,12 +164,12 @@ public class TrustedWebActivityTest {
intent.putExtra(CustomTabsIntent.EXTRA_TOOLBAR_COLOR, Color.GREEN);
launchCustomTabActivity(intent);
CustomTabActivity activity = mCustomTabActivityTestRule.getActivity();
waitForThemeColor(activity, Color.RED);
assertStatusBarColor(activity, Color.RED);
ThemeTestUtils.waitForThemeColor(activity, Color.RED);
ThemeTestUtils.assertStatusBarColor(activity, Color.RED);
mCustomTabActivityTestRule.loadUrl(pageWithoutThemeColor);
waitForThemeColor(activity, Color.GREEN);
assertStatusBarColor(activity, Color.GREEN);
ThemeTestUtils.waitForThemeColor(activity, Color.GREEN);
ThemeTestUtils.assertStatusBarColor(activity, Color.GREEN);
}
/**
......@@ -198,8 +194,8 @@ public class TrustedWebActivityTest {
addTrustedOriginToIntent(intent, pageWithThemeColorCertError);
launchCustomTabActivity(intent);
CustomTabActivity activity = mCustomTabActivityTestRule.getActivity();
waitForThemeColor(activity, Color.RED);
assertStatusBarColor(activity, Color.RED);
ThemeTestUtils.waitForThemeColor(activity, Color.RED);
ThemeTestUtils.assertStatusBarColor(activity, Color.RED);
spoofVerification(PACKAGE_NAME, pageWithThemeColorCertError);
ChromeTabUtils.loadUrlOnUiThread(activity.getActivityTab(), pageWithThemeColorCertError);
......@@ -208,8 +204,8 @@ public class TrustedWebActivityTest {
() -> { return TabThemeColorHelper.getDefaultColor(activity.getActivityTab()); });
int expectedColor =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? defaultColor : Color.BLACK;
waitForThemeColor(activity, defaultColor);
assertStatusBarColor(activity, expectedColor);
ThemeTestUtils.waitForThemeColor(activity, defaultColor);
ThemeTestUtils.assertStatusBarColor(activity, expectedColor);
}
public void launchCustomTabActivity(Intent intent) throws TimeoutException {
......@@ -219,39 +215,6 @@ public class TrustedWebActivityTest {
mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
}
/**
* Waits for the Tab's theme-color to change to the passed-in color.
*/
public static void waitForThemeColor(CustomTabActivity activity, int expectedColor)
throws ExecutionException, TimeoutException {
int themeColor = TestThreadUtils.runOnUiThreadBlocking(
() -> { return TabThemeColorHelper.getColor(activity.getActivityTab()); });
if (themeColor == expectedColor) {
return;
}
// Use longer-than-default timeout to give page time to finish loading.
CallbackHelper callbackHelper = new CallbackHelper();
activity.getActivityTab().addObserver(new EmptyTabObserver() {
@Override
public void onDidChangeThemeColor(Tab tab, int color) {
if (color == expectedColor) {
callbackHelper.notifyCalled();
}
}
});
callbackHelper.waitForFirst(10, TimeUnit.SECONDS);
}
/**
* Asserts that the status bar color equals the passed-in color.
*/
public static void assertStatusBarColor(CustomTabActivity activity, int expectedColor) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
expectedColor = ColorUtils.getDarkenedColorForStatusBar(expectedColor);
}
assertEquals(expectedColor, activity.getWindow().getStatusBarColor());
}
/**
* Test that trusted web activities show the toolbar when the page has a certificate error
* (and origin verification succeeds).
......
......@@ -10,6 +10,7 @@ import static org.chromium.base.ApplicationState.HAS_STOPPED_ACTIVITIES;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.LargeTest;
import android.support.test.filters.SmallTest;
......@@ -19,6 +20,7 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.runner.RunWith;
import org.chromium.base.ApiCompatibilityUtils;
......@@ -37,6 +39,7 @@ import org.chromium.chrome.browser.externalnav.ExternalNavigationHandler.Overrid
import org.chromium.chrome.browser.firstrun.FirstRunStatus;
import org.chromium.chrome.browser.tab.InterceptNavigationDelegateImpl;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.test.MockCertVerifierRuleAndroid;
import org.chromium.chrome.browser.ui.styles.ChromeColors;
import org.chromium.chrome.test.ChromeActivityTestRule;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
......@@ -61,20 +64,32 @@ import org.chromium.ui.base.PageTransition;
* Tests web navigations originating from a WebappActivity.
*/
@RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
ContentSwitches.HOST_RESOLVER_RULES + "=MAP * 127.0.0.1"})
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
public class WebappNavigationTest {
private static final String YOUTUBE_URL = "https://www.youtube.com/watch?v=EYmjoW4vIX8";
@Rule
public final WebappActivityTestRule mActivityTestRule = new WebappActivityTestRule();
@Rule
public final NativeLibraryTestRule mNativeLibraryTestRule = new NativeLibraryTestRule();
public MockCertVerifierRuleAndroid mCertVerifierRule =
new MockCertVerifierRuleAndroid(mNativeLibraryTestRule, 0 /* net::OK */);
@Rule
public RuleChain mRuleChain = RuleChain.emptyRuleChain()
.around(mActivityTestRule)
.around(mNativeLibraryTestRule)
.around(mCertVerifierRule);
@Before
public void setUp() {
mNativeLibraryTestRule.loadNativeLibraryNoBrowserProcess();
mActivityTestRule.getEmbeddedTestServerRule().setServerUsesHttps(true);
Uri mapToUri =
Uri.parse(mActivityTestRule.getEmbeddedTestServerRule().getServer().getURL("/"));
CommandLine.getInstance().appendSwitchWithValue(
ContentSwitches.HOST_RESOLVER_RULES, "MAP * " + mapToUri.getAuthority());
}
/**
......@@ -367,7 +382,7 @@ public class WebappNavigationTest {
}
@Test
@SmallTest
@LargeTest
@Feature({"Webapps"})
@RetryOnFailure
public void testCloseButtonReturnsToMostRecentInScopeUrl() throws Exception {
......@@ -379,10 +394,12 @@ public class WebappNavigationTest {
mActivityTestRule.loadUrlInTab(otherInScopeUrl, PageTransition.LINK, tab);
Assert.assertEquals(otherInScopeUrl, tab.getUrl());
mActivityTestRule.loadUrlInTab(offOriginUrl(), PageTransition.LINK, tab);
mActivityTestRule.loadUrlInTab(
offOriginUrl(), PageTransition.LINK, tab, 10 /* secondsToWait */);
String mozillaUrl = mActivityTestRule.getTestServer().getURLWithHostName(
"mozilla.org", "/defaultresponse");
mActivityTestRule.loadUrlInTab(mozillaUrl, PageTransition.LINK, tab);
mActivityTestRule.loadUrlInTab(
mozillaUrl, PageTransition.LINK, tab, 10 /* secondsToWait */);
// Toolbar with the close button should be visible.
WebappActivityTestRule.assertToolbarShowState(activity, true);
......
......@@ -4,31 +4,27 @@
package org.chromium.chrome.browser.webapps;
import android.annotation.TargetApi;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.support.test.filters.SmallTest;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.base.task.PostTask;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.MinAndroidSdkLevel;
import org.chromium.base.test.util.Restriction;
import org.chromium.chrome.browser.ChromeSwitches;
import org.chromium.chrome.browser.ShortcutHelper;
import org.chromium.chrome.browser.tab.TabTestUtils;
import org.chromium.chrome.browser.util.ColorUtils;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.content_public.browser.UiThreadTaskTraits;
import org.chromium.content_public.browser.test.util.Criteria;
import org.chromium.content_public.browser.test.util.CriteriaHelper;
import org.chromium.chrome.test.util.browser.ThemeTestUtils;
import org.chromium.ui.test.util.UiRestriction;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
/**
* Tests for splash screens with EXTRA_THEME_COLOR specified in the Intent.
......@@ -39,55 +35,41 @@ public class WebappSplashScreenThemeColorTest {
@Rule
public final WebappActivityTestRule mActivityTestRule = new WebappActivityTestRule();
@Before
public void setUp() {
mActivityTestRule.startWebappActivityAndWaitForSplashScreen(
mActivityTestRule
.createIntent()
// This is setting Color.Magenta with 50% opacity.
.putExtra(ShortcutHelper.EXTRA_THEME_COLOR, 0x80FF00FFL));
}
@Test
@DisabledTest
@SmallTest
@MinAndroidSdkLevel(Build.VERSION_CODES.LOLLIPOP_MR1)
@Restriction({UiRestriction.RESTRICTION_TYPE_PHONE})
// Customizing status bar color is disallowed for tablets.
@Feature({"Webapps"})
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void testThemeColorWhenSpecified() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return;
// This is Color.Magenta with 50% opacity.
final int intentThemeColor = Color.argb(0x80, 0xFF, 0, 0xFF);
Intent intent = mActivityTestRule.createIntent().putExtra(
ShortcutHelper.EXTRA_THEME_COLOR, (long) intentThemeColor);
mActivityTestRule.startWebappActivity(intent);
Assert.assertEquals(ColorUtils.getDarkenedColorForStatusBar(Color.MAGENTA),
mActivityTestRule.getActivity().getWindow().getStatusBarColor());
final int expectedThemeColor = Color.MAGENTA;
ThemeTestUtils.assertStatusBarColor(mActivityTestRule.getActivity(), expectedThemeColor);
}
@Test
@SmallTest
@MinAndroidSdkLevel(Build.VERSION_CODES.LOLLIPOP_MR1)
@Restriction({UiRestriction.RESTRICTION_TYPE_PHONE})
// Customizing status bar color is disallowed for tablets.
@Feature({"Webapps"})
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void testThemeColorNotUsedIfPagesHasOne() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return;
// Depending on the Android version, the status bar color will either be the same as the
// theme color or darker.
final int baseColor = Color.GREEN;
final int finalColor;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
finalColor = Color.GREEN;
} else {
finalColor = ColorUtils.getDarkenedColorForStatusBar(Color.GREEN);
}
PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT,
() -> TabTestUtils.simulateChangeThemeColor(
mActivityTestRule.getActivity().getActivityTab(), baseColor));
public void testThemeColorNotUsedIfPagesHasOne() throws ExecutionException, TimeoutException {
final int intentThemeColor = Color.MAGENTA;
final int pageThemeColor = Color.RED;
String pageWithThemeColorUrl = mActivityTestRule.getTestServer().getURL(
"/chrome/test/data/android/theme_color_test.html");
Intent intent =
mActivityTestRule.createIntent()
.putExtra(ShortcutHelper.EXTRA_URL, pageWithThemeColorUrl)
.putExtra(ShortcutHelper.EXTRA_THEME_COLOR, (long) intentThemeColor);
mActivityTestRule.startWebappActivity(intent);
// Waits for theme-color to change so the test doesn't rely on system timing.
CriteriaHelper.pollInstrumentationThread(
Criteria.equals(finalColor, new Callable<Integer>() {
@Override
public Integer call() {
return mActivityTestRule.getActivity().getWindow().getStatusBarColor();
}
}));
ThemeTestUtils.waitForThemeColor(mActivityTestRule.getActivity(), pageThemeColor);
ThemeTestUtils.assertStatusBarColor(mActivityTestRule.getActivity(), pageThemeColor);
}
}
......@@ -159,6 +159,7 @@ android_library("chrome_java_test_support") {
"javatests/src/org/chromium/chrome/test/util/browser/webapps/WebappTestHelper.java",
"javatests/src/org/chromium/chrome/test/util/browser/RecyclerViewTestUtils.java",
"javatests/src/org/chromium/chrome/test/util/browser/TabLoadObserver.java",
"javatests/src/org/chromium/chrome/test/util/browser/ThemeTestUtils.java",
"javatests/src/org/chromium/chrome/test/util/browser/tabmodel/MockTabModel.java",
"javatests/src/org/chromium/chrome/test/util/browser/tabmodel/MockTabModelSelector.java",
"javatests/src/org/chromium/chrome/test/util/browser/TabTitleObserver.java",
......
// Copyright 2019 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.test.util.browser;
import android.os.Build;
import org.junit.Assert;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.tab.TabThemeColorHelper;
import org.chromium.chrome.browser.util.ColorUtils;
import org.chromium.content_public.browser.test.util.Criteria;
import org.chromium.content_public.browser.test.util.CriteriaHelper;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
/**
* Utility methods for tests which customize the tab's theme color.
*/
public class ThemeTestUtils {
/**
* Waits for the activity active tab's theme-color to change to the passed-in color.
*/
public static void waitForThemeColor(ChromeActivity activity, int expectedColor)
throws ExecutionException, TimeoutException {
// Use longer-than-default timeout to give page time to finish loading.
CriteriaHelper.pollUiThread(
Criteria.equals(expectedColor,
() -> TabThemeColorHelper.getColor(activity.getActivityTab())),
10000, CriteriaHelper.DEFAULT_POLLING_INTERVAL);
}
/**
* Asserts that the status bar color equals the passed-in color.
*/
public static void assertStatusBarColor(ChromeActivity activity, int expectedColor) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
expectedColor = ColorUtils.getDarkenedColorForStatusBar(expectedColor);
}
Assert.assertEquals(expectedColor, activity.getWindow().getStatusBarColor());
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment