Commit d7fe32cc authored by chuanl's avatar chuanl Committed by Commit Bot

Use session params to hide CCT header while dynamic module is loading.

Dynamic module, when enabled, will not be availbe until native
initialization is finished. This causes an issue of showing CCT header
and then hiding it right away by dynamic module on a module managed URL.
By using session params, we can hide CCT header early until taken over
by dynamic module.

Bug: 882404
Change-Id: I57d60e70c1dc03a733e9093d235d816b3e220675
Reviewed-on: https://chromium-review.googlesource.com/c/1482463
Commit-Queue: John Lin <chuanl@google.com>
Reviewed-by: default avatarMichael van Ouwerkerk <mvanouwerkerk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#635105}
parent 5067fbf6
...@@ -1085,6 +1085,10 @@ public class CustomTabActivity extends ChromeActivity<CustomTabActivityComponent ...@@ -1085,6 +1085,10 @@ public class CustomTabActivity extends ChromeActivity<CustomTabActivityComponent
if (mIntentDataProvider.isTrustedWebActivity()) { if (mIntentDataProvider.isTrustedWebActivity()) {
component.resolveTrustedWebActivityCoordinator(); component.resolveTrustedWebActivityCoordinator();
} }
if (mConnection.shouldHideTopBarOnModuleManagedUrlsForSession(
mIntentDataProvider.getSession())) {
component.resolveDynamicModuleToolbarController();
}
return component; return component;
} }
......
...@@ -24,6 +24,7 @@ public class CustomTabBrowserControlsVisibilityDelegate ...@@ -24,6 +24,7 @@ public class CustomTabBrowserControlsVisibilityDelegate
private final Lazy<ChromeFullscreenManager> mFullscreenManagerDelegate; private final Lazy<ChromeFullscreenManager> mFullscreenManagerDelegate;
private final ActivityTabProvider mTabProvider; private final ActivityTabProvider mTabProvider;
private boolean mIsInTwaMode; private boolean mIsInTwaMode;
private boolean mIsInModuleLoadingMode;
@Inject @Inject
public CustomTabBrowserControlsVisibilityDelegate( public CustomTabBrowserControlsVisibilityDelegate(
...@@ -41,15 +42,24 @@ public class CustomTabBrowserControlsVisibilityDelegate ...@@ -41,15 +42,24 @@ public class CustomTabBrowserControlsVisibilityDelegate
return; return;
} }
mIsInTwaMode = isInTwaMode; mIsInTwaMode = isInTwaMode;
Tab activeTab = mTabProvider.getActivityTab(); updateActiveTabFullscreenEnabledState();
if (activeTab != null) { }
activeTab.updateFullscreenEnabledState();
/**
* Sets module loading mode. In module loading mode browser controls should be hidden.
*/
public void setModuleLoadingMode(boolean isInModuleLoadingMode) {
if (mIsInModuleLoadingMode == isInModuleLoadingMode) {
return;
} }
mIsInModuleLoadingMode = isInModuleLoadingMode;
updateActiveTabFullscreenEnabledState();
} }
@Override @Override
public boolean canShowBrowserControls() { public boolean canShowBrowserControls() {
return !mIsInTwaMode && getDefaultVisibilityDelegate().canShowBrowserControls(); return !mIsInTwaMode && !mIsInModuleLoadingMode
&& getDefaultVisibilityDelegate().canShowBrowserControls();
} }
@Override @Override
...@@ -60,4 +70,11 @@ public class CustomTabBrowserControlsVisibilityDelegate ...@@ -60,4 +70,11 @@ public class CustomTabBrowserControlsVisibilityDelegate
private BrowserStateBrowserControlsVisibilityDelegate getDefaultVisibilityDelegate() { private BrowserStateBrowserControlsVisibilityDelegate getDefaultVisibilityDelegate() {
return mFullscreenManagerDelegate.get().getBrowserVisibilityDelegate(); return mFullscreenManagerDelegate.get().getBrowserVisibilityDelegate();
} }
private void updateActiveTabFullscreenEnabledState() {
Tab activeTab = mTabProvider.getActivityTab();
if (activeTab != null) {
activeTab.updateFullscreenEnabledState();
}
}
} }
...@@ -1007,6 +1007,11 @@ public class CustomTabsConnection { ...@@ -1007,6 +1007,11 @@ public class CustomTabsConnection {
mClientManager.setCanUseHiddenTab(session, value); mClientManager.setCanUseHiddenTab(session, value);
} }
@VisibleForTesting
void setHideCCTTopBarOnModuleManagedUrls(CustomTabsSessionToken session, boolean value) {
mClientManager.setHideCCTTopBarOnModuleManagedUrls(session, value);
}
/** /**
* See {@link ClientManager#setSendNavigationInfoForSession(CustomTabsSessionToken, boolean)}. * See {@link ClientManager#setSendNavigationInfoForSession(CustomTabsSessionToken, boolean)}.
*/ */
......
...@@ -14,6 +14,7 @@ import org.chromium.chrome.browser.customtabs.TabObserverRegistrar; ...@@ -14,6 +14,7 @@ import org.chromium.chrome.browser.customtabs.TabObserverRegistrar;
import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabController; import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabController;
import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabFactory; import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabFactory;
import org.chromium.chrome.browser.customtabs.dynamicmodule.DynamicModuleCoordinator; import org.chromium.chrome.browser.customtabs.dynamicmodule.DynamicModuleCoordinator;
import org.chromium.chrome.browser.customtabs.dynamicmodule.DynamicModuleToolbarController;
import org.chromium.chrome.browser.dependency_injection.ActivityScope; import org.chromium.chrome.browser.dependency_injection.ActivityScope;
import org.chromium.chrome.browser.dependency_injection.ChromeActivityCommonsModule; import org.chromium.chrome.browser.dependency_injection.ChromeActivityCommonsModule;
import org.chromium.chrome.browser.dependency_injection.ChromeActivityComponent; import org.chromium.chrome.browser.dependency_injection.ChromeActivityComponent;
...@@ -29,6 +30,7 @@ import dagger.Subcomponent; ...@@ -29,6 +30,7 @@ import dagger.Subcomponent;
@ActivityScope @ActivityScope
public interface CustomTabActivityComponent extends ChromeActivityComponent { public interface CustomTabActivityComponent extends ChromeActivityComponent {
TrustedWebActivityCoordinator resolveTrustedWebActivityCoordinator(); TrustedWebActivityCoordinator resolveTrustedWebActivityCoordinator();
DynamicModuleToolbarController resolveDynamicModuleToolbarController();
DynamicModuleCoordinator resolveDynamicModuleCoordinator(); DynamicModuleCoordinator resolveDynamicModuleCoordinator();
CloseButtonNavigator resolveCloseButtonNavigator(); CloseButtonNavigator resolveCloseButtonNavigator();
......
...@@ -72,6 +72,7 @@ public class DynamicModuleCoordinator implements NativeInitObserver, Destroyable ...@@ -72,6 +72,7 @@ public class DynamicModuleCoordinator implements NativeInitObserver, Destroyable
private final Lazy<CustomTabTopBarDelegate> mTopBarDelegate; private final Lazy<CustomTabTopBarDelegate> mTopBarDelegate;
private final Lazy<CustomTabBottomBarDelegate> mBottomBarDelegate; private final Lazy<CustomTabBottomBarDelegate> mBottomBarDelegate;
private final Lazy<ChromeFullscreenManager> mFullscreenManager; private final Lazy<ChromeFullscreenManager> mFullscreenManager;
private final Lazy<DynamicModuleToolbarController> mToolbarController;
@Nullable @Nullable
private LoadModuleCallback mModuleCallback; private LoadModuleCallback mModuleCallback;
...@@ -166,6 +167,7 @@ public class DynamicModuleCoordinator implements NativeInitObserver, Destroyable ...@@ -166,6 +167,7 @@ public class DynamicModuleCoordinator implements NativeInitObserver, Destroyable
Lazy<CustomTabTopBarDelegate> topBarDelegate, Lazy<CustomTabTopBarDelegate> topBarDelegate,
Lazy<CustomTabBottomBarDelegate> bottomBarDelegate, Lazy<CustomTabBottomBarDelegate> bottomBarDelegate,
Lazy<ChromeFullscreenManager> fullscreenManager, Lazy<ChromeFullscreenManager> fullscreenManager,
Lazy<DynamicModuleToolbarController> toolbarController,
CustomTabsConnection connection, ChromeActivity activity, CustomTabsConnection connection, ChromeActivity activity,
CustomTabActivityTabController tabController, CustomTabActivityTabController tabController,
DynamicModulePageLoadObserver pageLoadObserver) { DynamicModulePageLoadObserver pageLoadObserver) {
...@@ -186,6 +188,7 @@ public class DynamicModuleCoordinator implements NativeInitObserver, Destroyable ...@@ -186,6 +188,7 @@ public class DynamicModuleCoordinator implements NativeInitObserver, Destroyable
mTopBarDelegate = topBarDelegate; mTopBarDelegate = topBarDelegate;
mBottomBarDelegate = bottomBarDelegate; mBottomBarDelegate = bottomBarDelegate;
mFullscreenManager = fullscreenManager; mFullscreenManager = fullscreenManager;
mToolbarController = toolbarController;
mPageCriteria = url -> (isModuleLoading() || isModuleLoaded()) && isModuleManagedUrl(url); mPageCriteria = url -> (isModuleLoading() || isModuleLoaded()) && isModuleManagedUrl(url);
closeButtonNavigator.setLandingPageCriteria(mPageCriteria); closeButtonNavigator.setLandingPageCriteria(mPageCriteria);
...@@ -337,6 +340,7 @@ public class DynamicModuleCoordinator implements NativeInitObserver, Destroyable ...@@ -337,6 +340,7 @@ public class DynamicModuleCoordinator implements NativeInitObserver, Destroyable
private class LoadModuleCallback implements Callback<ModuleEntryPoint> { private class LoadModuleCallback implements Callback<ModuleEntryPoint> {
@Override @Override
public void onResult(@Nullable ModuleEntryPoint entryPoint) { public void onResult(@Nullable ModuleEntryPoint entryPoint) {
mToolbarController.get().releaseAndroidControlsHidingToken();
mDefaultToolbarVisibility = mActivity.getToolbarManager().getToolbarVisibility(); mDefaultToolbarVisibility = mActivity.getToolbarManager().getToolbarVisibility();
mDefaultToolbarShadowVisibility = mDefaultToolbarShadowVisibility =
mActivity.getToolbarManager().getToolbarShadowVisibility(); mActivity.getToolbarManager().getToolbarShadowVisibility();
...@@ -466,7 +470,9 @@ public class DynamicModuleCoordinator implements NativeInitObserver, Destroyable ...@@ -466,7 +470,9 @@ public class DynamicModuleCoordinator implements NativeInitObserver, Destroyable
} }
private void maybeCustomizeCctHeader(String url) { private void maybeCustomizeCctHeader(String url) {
if (!isModuleLoaded() && !isModuleLoading() && !hasModuleFailedToLoad()) return; // Since some of the tool bar default settings are not obtained until module loading is
// finished, we do not allow customization until then.
if (!isModuleLoaded() && !hasModuleFailedToLoad()) return;
boolean showTopBar = mPageCriteria.matches(url); boolean showTopBar = mPageCriteria.matches(url);
mTopBarDelegate.get().showTopBarIfNecessary(showTopBar); mTopBarDelegate.get().showTopBarIfNecessary(showTopBar);
......
// 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.browser.customtabs.dynamicmodule;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.browser.customtabs.CustomTabBrowserControlsVisibilityDelegate;
import org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider;
import org.chromium.chrome.browser.dependency_injection.ActivityScope;
import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager;
import org.chromium.chrome.browser.fullscreen.FullscreenManager;
import org.chromium.chrome.browser.init.ActivityLifecycleDispatcher;
import org.chromium.chrome.browser.lifecycle.InflationObserver;
import org.chromium.chrome.browser.lifecycle.NativeInitObserver;
import javax.inject.Inject;
import dagger.Lazy;
/**
* Controls the visibility of the toolbar on module managed URLs.
*/
@ActivityScope
public class DynamicModuleToolbarController implements InflationObserver, NativeInitObserver {
private final Lazy<ChromeFullscreenManager> mFullscreenManager;
private final CustomTabBrowserControlsVisibilityDelegate mControlsVisibilityDelegate;
private final CustomTabIntentDataProvider mIntentDataProvider;
private int mControlsHidingToken = FullscreenManager.INVALID_TOKEN;
private boolean mHasReleasedToken;
@Inject
public DynamicModuleToolbarController(Lazy<ChromeFullscreenManager> fullscreenManager,
CustomTabBrowserControlsVisibilityDelegate controlsVisibilityDelegate,
CustomTabIntentDataProvider intentDataProvider,
ActivityLifecycleDispatcher activityLifecycleDispatcher) {
this.mFullscreenManager = fullscreenManager;
this.mControlsVisibilityDelegate = controlsVisibilityDelegate;
this.mIntentDataProvider = intentDataProvider;
activityLifecycleDispatcher.register(this);
}
@Override
public void onPreInflationStartup() {}
@Override
public void onPostInflationStartup() {
mControlsVisibilityDelegate.setModuleLoadingMode(true);
mControlsHidingToken =
mFullscreenManager.get().hideAndroidControlsAndClearOldToken(mControlsHidingToken);
mHasReleasedToken = false;
}
@Override
public void onFinishNativeInitialization() {
if (!mIntentDataProvider.isDynamicModuleEnabled()) {
releaseAndroidControlsHidingToken();
}
}
/* package */ void releaseAndroidControlsHidingToken() {
mControlsVisibilityDelegate.setModuleLoadingMode(false);
mFullscreenManager.get().releaseAndroidControlsHidingToken(mControlsHidingToken);
mHasReleasedToken = true;
}
@VisibleForTesting
boolean hasReleasedToken() {
return mHasReleasedToken;
}
@VisibleForTesting
boolean hasAcquiredToken() {
return mControlsHidingToken != FullscreenManager.INVALID_TOKEN;
}
}
...@@ -506,6 +506,7 @@ chrome_java_sources = [ ...@@ -506,6 +506,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleCoordinator.java", "java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleCoordinator.java",
"java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleNavigationEventObserver.java", "java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleNavigationEventObserver.java",
"java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModulePageLoadObserver.java", "java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModulePageLoadObserver.java",
"java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleToolbarController.java",
"java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleEntryPoint.java", "java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleEntryPoint.java",
"java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleHostImpl.java", "java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleHostImpl.java",
"java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleLoader.java", "java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleLoader.java",
......
...@@ -15,6 +15,7 @@ import android.support.customtabs.CustomTabsClient; ...@@ -15,6 +15,7 @@ import android.support.customtabs.CustomTabsClient;
import android.support.customtabs.CustomTabsIntent; import android.support.customtabs.CustomTabsIntent;
import android.support.customtabs.CustomTabsServiceConnection; import android.support.customtabs.CustomTabsServiceConnection;
import android.support.customtabs.CustomTabsSession; import android.support.customtabs.CustomTabsSession;
import android.support.customtabs.CustomTabsSessionToken;
import android.support.test.InstrumentationRegistry; import android.support.test.InstrumentationRegistry;
import org.junit.Assert; import org.junit.Assert;
...@@ -106,4 +107,12 @@ public class CustomTabsTestUtils { ...@@ -106,4 +107,12 @@ public class CustomTabsTestUtils {
CriteriaHelper.pollUiThread( CriteriaHelper.pollUiThread(
activity.getAppMenuHandler()::isAppMenuShowing, "App menu was not shown"); activity.getAppMenuHandler()::isAppMenuShowing, "App menu was not shown");
} }
public static void setHideCctTopBarOnModuleManagedUrls(Intent intent, boolean hideCctTopBar)
throws InterruptedException, TimeoutException {
CustomTabsConnection connection = warmUpAndWait();
CustomTabsSessionToken token = CustomTabsSessionToken.getSessionTokenFromIntent(intent);
connection.newSession(token);
connection.setHideCCTTopBarOnModuleManagedUrls(token, hideCctTopBar);
}
} }
...@@ -532,6 +532,54 @@ public class CustomTabsDynamicModuleUITest { ...@@ -532,6 +532,54 @@ public class CustomTabsDynamicModuleUITest {
runOnUiThreadBlocking(() -> Assert.assertTrue(canChangeProgressBarTopMargin())); 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() { private void assertNoTopBar() {
runOnUiThreadBlocking(() -> { runOnUiThreadBlocking(() -> {
ViewGroup topBar = getActivity().findViewById(R.id.topbar); ViewGroup topBar = getActivity().findViewById(R.id.topbar);
......
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