blob: 0275e73403638dddc8850ee56e0c7ecbf0c3b46e [file] [log] [blame]
// Copyright 2020 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.browserservices.ui.splashscreen.webapps;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.net.Uri;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import org.chromium.base.ContextUtils;
import org.chromium.base.FileUtils;
import org.chromium.base.StrictModeContext;
import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider;
import org.chromium.chrome.browser.browserservices.ui.splashscreen.SplashController;
import org.chromium.chrome.browser.browserservices.ui.splashscreen.SplashDelegate;
import org.chromium.chrome.browser.customtabs.content.TabObserverRegistrar;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.webapps.WebApkSplashNetworkErrorObserver;
import org.chromium.chrome.browser.webapps.WebappDataStorage;
import org.chromium.chrome.browser.webapps.WebappInfo;
import org.chromium.chrome.browser.webapps.WebappRegistry;
import org.chromium.ui.util.ColorUtils;
import org.chromium.webapk.lib.common.WebApkCommonUtils;
import org.chromium.webapk.lib.common.splash.SplashLayout;
import javax.inject.Inject;
/**
* Displays the splash screen for homescreen shortcuts and WebAPKs.
*/
public class WebappSplashController implements SplashDelegate {
public static final int HIDE_ANIMATION_DURATION_MS = 300;
private SplashController mSplashController;
private TabObserverRegistrar mTabObserverRegistrar;
private WebappInfo mWebappInfo;
private WebApkSplashNetworkErrorObserver mWebApkNetworkErrorObserver;
@Inject
public WebappSplashController(SplashController splashController, Activity activity,
TabObserverRegistrar tabObserverRegistrar,
BrowserServicesIntentDataProvider intentDataProvider) {
mSplashController = splashController;
mTabObserverRegistrar = tabObserverRegistrar;
mWebappInfo = WebappInfo.create(intentDataProvider);
mSplashController.setConfig(this, HIDE_ANIMATION_DURATION_MS);
if (mWebappInfo.isForWebApk()) {
mWebApkNetworkErrorObserver =
new WebApkSplashNetworkErrorObserver(activity, mWebappInfo.name());
mTabObserverRegistrar.registerTabObserver(mWebApkNetworkErrorObserver);
}
}
@Override
public View buildSplashView() {
Context appContext = ContextUtils.getApplicationContext();
int backgroundColor =
ColorUtils.getOpaqueColor(mWebappInfo.backgroundColorFallbackToDefault());
if (mWebappInfo.isSplashProvidedByWebApk()) {
return buildSplashWithWebApkProvidedScreenshot(appContext, backgroundColor);
}
return buildSplashFromWebApkInfo(appContext, backgroundColor);
}
@Override
public void onSplashHidden(Tab tab, long startTimestamp, long endTimestamp) {
if (mWebApkNetworkErrorObserver != null) {
mTabObserverRegistrar.unregisterTabObserver(mWebApkNetworkErrorObserver);
tab.removeObserver(mWebApkNetworkErrorObserver);
mWebApkNetworkErrorObserver = null;
}
}
@Override
public boolean shouldWaitForSubsequentPageLoadToHideSplash() {
return mWebApkNetworkErrorObserver != null
&& mWebApkNetworkErrorObserver.isNetworkErrorDialogVisible();
}
/** Builds splash screen from WebApkInfo. */
private View buildSplashFromWebApkInfo(Context appContext, int backgroundColor) {
ViewGroup splashScreen = new FrameLayout(appContext);
splashScreen.setBackgroundColor(backgroundColor);
if (mWebappInfo.isForWebApk()) {
initializeWebApkInfoSplashLayout(splashScreen, backgroundColor,
mWebappInfo.splashIcon().bitmap(), mWebappInfo.isSplashIconMaskable());
return splashScreen;
}
WebappDataStorage storage =
WebappRegistry.getInstance().getWebappDataStorage(mWebappInfo.id());
if (storage == null) {
initializeWebApkInfoSplashLayout(splashScreen, backgroundColor, null, false);
return splashScreen;
}
storage.getSplashScreenImage(new WebappDataStorage.FetchCallback<Bitmap>() {
@Override
public void onDataRetrieved(Bitmap splashImage) {
initializeWebApkInfoSplashLayout(splashScreen, backgroundColor, splashImage, false);
}
});
return splashScreen;
}
private void initializeWebApkInfoSplashLayout(ViewGroup splashScreen, int backgroundColor,
Bitmap splashImage, boolean isSplashIconMaskable) {
Context context = ContextUtils.getApplicationContext();
Resources resources = context.getResources();
Bitmap selectedIcon = splashImage;
boolean selectedIconGenerated = false;
boolean selectedIconAdaptive = isSplashIconMaskable;
if (selectedIcon == null) {
selectedIcon = mWebappInfo.icon().bitmap();
selectedIconGenerated = mWebappInfo.isIconGenerated();
selectedIconAdaptive = mWebappInfo.isIconAdaptive();
}
SplashLayout.createLayout(context, splashScreen, selectedIcon, selectedIconAdaptive,
selectedIconGenerated, mWebappInfo.name(),
ColorUtils.shouldUseLightForegroundOnBackground(backgroundColor));
}
/** Builds splash screen using screenshot provided by WebAPK. */
private View buildSplashWithWebApkProvidedScreenshot(Context appContext, int backgroundColor) {
ImageView splashView = new ImageView(appContext);
splashView.setBackgroundColor(backgroundColor);
Bitmap splashBitmap = null;
try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) {
splashBitmap = FileUtils.queryBitmapFromContentProvider(appContext,
Uri.parse(WebApkCommonUtils.generateSplashContentProviderUri(
mWebappInfo.webApkPackageName())));
}
if (splashBitmap != null) {
splashView.setScaleType(ImageView.ScaleType.FIT_CENTER);
splashView.setImageBitmap(splashBitmap);
}
return splashView;
}
}