Commit 339c424d authored by Sicheng Li's avatar Sicheng Li Committed by Commit Bot

Supports lock screenOrientation for TWA 1/2

1. Adds the CustomTabOrientationController in SharedActivityCoordinator
2. Calls the setCanControlOrientaton() in the
SharedActivityCoordinator#updateUi()
3. Implements the CustomTabOrientationController#setCanControlOrientaton()
4. Modifies the method of mapping orientation from AndroidX (convertOrientationType()) to chromium
as we now take int as parameter instead of String
5. Imports ScreenOrientationLockType class to handle lock type
6. Adds a method as ScreenOrientationProviderImpl#setOverrideDefaultOrientation() to get
the default screen orientation lock for TWAs or WebAPKs.


Bug: 812797,989606
Change-Id: If07122814a7ca0e68f40fa70d9df24c68e3c5ccf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2276255Reviewed-by: default avatarMounir Lamouri <mlamouri@chromium.org>
Reviewed-by: default avatarPeter Conn <peconn@chromium.org>
Reviewed-by: default avatarPeter Kotwicz <pkotwicz@chromium.org>
Reviewed-by: default avatarYaron Friedman <yfriedman@chromium.org>
Commit-Queue: Sicheng Li <scli@google.com>
Auto-Submit: Sicheng Li <scli@google.com>
Cr-Commit-Position: refs/heads/master@{#792142}
parent ce79e3ce
......@@ -23,6 +23,7 @@ import org.chromium.chrome.browser.customtabs.CustomButtonParams;
import org.chromium.chrome.browser.flags.ActivityType;
import org.chromium.chrome.browser.webapps.WebApkExtras;
import org.chromium.chrome.browser.webapps.WebappExtras;
import org.chromium.device.mojom.ScreenOrientationLockType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
......@@ -359,6 +360,13 @@ public abstract class BrowserServicesIntentDataProvider {
return null;
}
/**
* Returns {@link ScreenOrientationLockType} supplied in the intent.
*/
public int getDefaultOrientation() {
return ScreenOrientationLockType.DEFAULT;
}
/**
* @return The component name of the module entry point, or null if not specified.
*/
......
......@@ -15,6 +15,7 @@ import org.chromium.chrome.browser.browserservices.trustedwebactivityui.controll
import org.chromium.chrome.browser.browserservices.ui.controller.CurrentPageVerifier;
import org.chromium.chrome.browser.browserservices.ui.controller.CurrentPageVerifier.VerificationStatus;
import org.chromium.chrome.browser.browserservices.ui.controller.Verifier;
import org.chromium.chrome.browser.customtabs.CustomTabOrientationController;
import org.chromium.chrome.browser.customtabs.CustomTabStatusBarColorProvider;
import org.chromium.chrome.browser.customtabs.content.CustomTabActivityNavigationController;
import org.chromium.chrome.browser.customtabs.features.ImmersiveModeController;
......@@ -40,6 +41,7 @@ public class SharedActivityCoordinator implements InflationObserver {
private final CustomTabToolbarColorController mToolbarColorController;
private final CustomTabStatusBarColorProvider mStatusBarColorProvider;
private final Lazy<ImmersiveModeController> mImmersiveModeController;
private final CustomTabOrientationController mCustomTabOrientationController;
@Nullable
private final ImmersiveMode mImmersiveDisplayMode;
......@@ -54,7 +56,8 @@ public class SharedActivityCoordinator implements InflationObserver {
CustomTabStatusBarColorProvider statusBarColorProvider,
ActivityLifecycleDispatcher lifecycleDispatcher,
TrustedWebActivityBrowserControlsVisibilityManager browserControlsVisibilityManager,
Lazy<ImmersiveModeController> immersiveModeController) {
Lazy<ImmersiveModeController> immersiveModeController,
CustomTabOrientationController customTabOrientationController) {
mCurrentPageVerifier = currentPageVerifier;
mIntentDataProvider = intentDataProvider;
mBrowserControlsVisibilityManager = browserControlsVisibilityManager;
......@@ -62,6 +65,7 @@ public class SharedActivityCoordinator implements InflationObserver {
mStatusBarColorProvider = statusBarColorProvider;
mImmersiveModeController = immersiveModeController;
mImmersiveDisplayMode = computeImmersiveMode(intentDataProvider);
mCustomTabOrientationController = customTabOrientationController;
navigationController.setLandingPageOnCloseCriterion(verifier::wasPreviouslyVerified);
......@@ -105,6 +109,7 @@ public class SharedActivityCoordinator implements InflationObserver {
mBrowserControlsVisibilityManager.updateIsInAppMode(useAppModeUi);
mToolbarColorController.setUseTabThemeColor(useAppModeUi);
mStatusBarColorProvider.setUseTabThemeColor(useAppModeUi);
mCustomTabOrientationController.setCanControlOrientation(useAppModeUi);
}
private void updateImmersiveMode(boolean inAppMode) {
......
......@@ -30,6 +30,7 @@ import androidx.browser.customtabs.CustomTabColorSchemeParams;
import androidx.browser.customtabs.CustomTabsIntent;
import androidx.browser.customtabs.CustomTabsSessionToken;
import androidx.browser.customtabs.TrustedWebUtils;
import androidx.browser.trusted.ScreenOrientation;
import androidx.browser.trusted.TrustedWebActivityDisplayMode;
import androidx.browser.trusted.TrustedWebActivityIntentBuilder;
import androidx.browser.trusted.sharing.ShareData;
......@@ -48,6 +49,7 @@ import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.components.browser_ui.styles.ChromeColors;
import org.chromium.components.browser_ui.widget.TintedDrawable;
import org.chromium.components.embedder_support.util.UrlConstants;
import org.chromium.device.mojom.ScreenOrientationLockType;
import org.chromium.ui.util.ColorUtils;
import java.lang.annotation.Retention;
......@@ -205,6 +207,7 @@ public class CustomTabIntentDataProvider extends BrowserServicesIntentDataProvid
/** ISO 639 language code */
@Nullable
private final String mTranslateLanguage;
private final int mDefaultOrientation;
/**
* Add extras to customize menu items for opening payment request UI custom tab from Chrome.
......@@ -347,6 +350,10 @@ public class CustomTabIntentDataProvider extends BrowserServicesIntentDataProvid
mTranslateLanguage = IntentUtils.safeGetStringExtra(intent, EXTRA_TRANSLATE_LANGUAGE);
mFocusIntent = IntentUtils.safeGetParcelableExtra(intent, EXTRA_FOCUS_INTENT);
// Import the {@link ScreenOrientation}.
mDefaultOrientation = convertOrientationType(IntentUtils.safeGetIntExtra(intent,
TrustedWebActivityIntentBuilder.EXTRA_SCREEN_ORIENTATION,
ScreenOrientation.DEFAULT));
}
/**
......@@ -535,6 +542,44 @@ public class CustomTabIntentDataProvider extends BrowserServicesIntentDataProvid
}
}
/**
* Returns the {@link ScreenOrientationLockType} which matches {@link ScreenOrientation}.
* @param orientation {@link ScreenOrientation}
* @return The matching ScreenOrientationLockType. {@link ScreenOrientationLockType#DEFAULT} if
* there is no match.
*/
private static int convertOrientationType(@ScreenOrientation.LockType int orientation) {
switch (orientation) {
case ScreenOrientation.DEFAULT:
return ScreenOrientationLockType.DEFAULT;
case ScreenOrientation.PORTRAIT_PRIMARY:
return ScreenOrientationLockType.PORTRAIT_PRIMARY;
case ScreenOrientation.PORTRAIT_SECONDARY:
return ScreenOrientationLockType.PORTRAIT_SECONDARY;
case ScreenOrientation.LANDSCAPE_PRIMARY:
return ScreenOrientationLockType.LANDSCAPE_PRIMARY;
case ScreenOrientation.LANDSCAPE_SECONDARY:
return ScreenOrientationLockType.LANDSCAPE_SECONDARY;
case ScreenOrientation.ANY:
return ScreenOrientationLockType.ANY;
case ScreenOrientation.LANDSCAPE:
return ScreenOrientationLockType.LANDSCAPE;
case ScreenOrientation.PORTRAIT:
return ScreenOrientationLockType.PORTRAIT;
case ScreenOrientation.NATURAL:
return ScreenOrientationLockType.NATURAL;
default:
Log.w(TAG, "The provided orientaton is not supported, orientation = %d",
orientation);
return ScreenOrientationLockType.DEFAULT;
}
}
@Override
public int getDefaultOrientation() {
return mDefaultOrientation;
}
@Override
public @ActivityType int getActivityType() {
return mActivityType;
......
......@@ -10,9 +10,6 @@ import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProv
import org.chromium.chrome.browser.browserservices.ui.splashscreen.SplashController;
import org.chromium.chrome.browser.browserservices.ui.splashscreen.SplashscreenObserver;
import org.chromium.chrome.browser.dependency_injection.ActivityScope;
import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
import org.chromium.chrome.browser.lifecycle.InflationObserver;
import org.chromium.chrome.browser.webapps.WebappExtras;
import org.chromium.content_public.browser.ScreenOrientationProvider;
import org.chromium.device.mojom.ScreenOrientationLockType;
import org.chromium.ui.base.ActivityWindowAndroid;
......@@ -24,24 +21,16 @@ import javax.inject.Inject;
* Delays all screen orientation requests till the activity translucency is removed.
*/
@ActivityScope
public class CustomTabOrientationController implements InflationObserver {
public class CustomTabOrientationController {
private final ActivityWindowAndroid mActivityWindowAndroid;
private final ActivityLifecycleDispatcher mLifecycleDispatcher;
private int mLockScreenOrientation = ScreenOrientationLockType.DEFAULT;
private int mLockScreenOrientation;
@Inject
public CustomTabOrientationController(ActivityWindowAndroid activityWindowAndroid,
BrowserServicesIntentDataProvider intentDataProvider,
ActivityLifecycleDispatcher lifecycleDispatcher) {
BrowserServicesIntentDataProvider intentDataProvider) {
mActivityWindowAndroid = activityWindowAndroid;
mLifecycleDispatcher = lifecycleDispatcher;
WebappExtras webappExtras = intentDataProvider.getWebappExtras();
if (webappExtras != null) {
mLockScreenOrientation = webappExtras.orientation;
mLifecycleDispatcher.register(this);
}
mLockScreenOrientation = intentDataProvider.getDefaultOrientation();
}
/**
......@@ -71,16 +60,12 @@ public class CustomTabOrientationController implements InflationObserver {
});
}
@Override
public void onPreInflationStartup() {
mLifecycleDispatcher.unregister(this);
public void setCanControlOrientation(boolean inAppMode) {
int defaultWebOrientation =
inAppMode ? mLockScreenOrientation : ScreenOrientationLockType.DEFAULT;
ScreenOrientationProvider.getInstance().setOverrideDefaultOrientation(
mActivityWindowAndroid, (byte) defaultWebOrientation);
// Queue up default screen orientation request now because the web page might change it via
// JavaScript.
ScreenOrientationProvider.getInstance().lockOrientation(
mActivityWindowAndroid, (byte) mLockScreenOrientation);
ScreenOrientationProvider.getInstance().unlockOrientation(mActivityWindowAndroid);
}
@Override
public void onPostInflationStartup() {}
}
......@@ -128,4 +128,9 @@ public class WebappIntentDataProvider extends BrowserServicesIntentDataProvider
public WebApkExtras getWebApkExtras() {
return mWebApkExtras;
}
@Override
public int getDefaultOrientation() {
return mWebappExtras.orientation;
}
}
......@@ -123,8 +123,6 @@ public class WebApkInitializationTest {
WebappDisclosureSnackbarController.class.getName()));
assertTrue(registeredObserverClassNames.contains(
WebApkActivityLifecycleUmaTracker.class.getName()));
assertTrue(registeredObserverClassNames.contains(
CustomTabOrientationController.class.getName()));
assertTrue(
registeredObserverClassNames.contains(SharedActivityCoordinator.class.getName()));
......
......@@ -44,6 +44,14 @@ public class ScreenOrientationProviderImpl
private ScreenOrientationDelegate mDelegate;
/**
* The keys of the map are the activities for which screen orientation are
* trying to lock.
* The values of the map are the most recent default web screen orientation request for each
* activity.
*/
private Map<Activity, Byte> mDefaultOrientationOverrides = new WeakHashMap<>();
/**
* The keys of the map are the activities for which screen orientation requests are
* delayed.
......@@ -139,13 +147,17 @@ public class ScreenOrientationProviderImpl
// Note that we can't just use the focused activity, as that would lead to bugs where
// unlockOrientation unlocks a different activity to the one that was locked.
if (activity == null) return;
byte mDefaultWebOrientation = (byte) ScreenOrientationLockType.DEFAULT;
if (mDefaultOrientationOverrides.containsKey(activity)) {
mDefaultWebOrientation = mDefaultOrientationOverrides.get(activity);
}
int defaultOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
// Activities opened from a shortcut may have EXTRA_ORIENTATION set. In
// which case, we want to use that as the default orientation.
int orientation = activity.getIntent().getIntExtra(
ScreenOrientationConstants.EXTRA_ORIENTATION, ScreenOrientationLockType.DEFAULT);
ScreenOrientationConstants.EXTRA_ORIENTATION, mDefaultWebOrientation);
defaultOrientation = getOrientationFromWebScreenOrientations(
(byte) orientation, window, activity);
......@@ -199,6 +211,20 @@ public class ScreenOrientationProviderImpl
mDelegate = delegate;
}
@Override
public void setOverrideDefaultOrientation(WindowAndroid window, byte defaultWebOrientation) {
if (window == null) return;
Activity activity = window.getActivity().get();
if (activity == null) return;
if (defaultWebOrientation != ScreenOrientationLockType.DEFAULT) {
mDefaultOrientationOverrides.put(activity, defaultWebOrientation);
} else {
mDefaultOrientationOverrides.remove(activity);
}
}
/** Returns whether screen orientation requests are delayed for the passed-in activity. */
private boolean areRequestsDelayedForActivity(Activity activity) {
return mDelayedRequests.containsKey(activity);
......
......@@ -24,6 +24,10 @@ public interface ScreenOrientationProvider {
*/
void lockOrientation(@Nullable WindowAndroid window, byte webScreenOrientation);
/**
* Unlocks screen orientation.
* @param window Window to unlock rotation on.
*/
void unlockOrientation(@Nullable WindowAndroid window);
/** Delays screen orientation requests for the given window. */
......@@ -33,4 +37,11 @@ public interface ScreenOrientationProvider {
void runDelayedOrientationRequests(WindowAndroid window);
void setOrientationDelegate(ScreenOrientationDelegate delegate);
/**
* Sets a default screen orientation for a given window.
* @param window Window to lock rotation on.
* @param defaultWebOrientation a default screen orientation for the window.
*/
void setOverrideDefaultOrientation(WindowAndroid window, byte defaultWebOrientation);
}
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