| Index: chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegateAndroid.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegateAndroid.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegateAndroid.java
|
| index 989024241efeb1c31242977cc736eee29bf2dc45..4954dd35defae263a1affde7f6d3000ee5ca9e79 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegateAndroid.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegateAndroid.java
|
| @@ -11,15 +11,19 @@ import android.content.Intent;
|
| import android.content.pm.PackageManager;
|
| import android.os.Looper;
|
|
|
| +import org.chromium.base.ApplicationState;
|
| import org.chromium.base.ApplicationStatus;
|
| import org.chromium.base.ContextUtils;
|
| +import org.chromium.base.ThreadUtils;
|
| import org.chromium.base.VisibleForTesting;
|
| import org.chromium.base.annotations.CalledByNative;
|
| import org.chromium.base.annotations.JNINamespace;
|
| +import org.chromium.chrome.R;
|
| import org.chromium.chrome.browser.banners.AppData;
|
| import org.chromium.chrome.browser.banners.InstallerDelegate;
|
| import org.chromium.chrome.browser.tab.Tab;
|
| import org.chromium.ui.base.WindowAndroid;
|
| +import org.chromium.ui.widget.Toast;
|
|
|
| /**
|
| * Handles the promotion and installation of an app specified by the current web page. This Java
|
| @@ -39,6 +43,23 @@ public class AppBannerInfoBarDelegateAndroid {
|
| /** Monitors for application state changes. */
|
| private final ApplicationStatus.ApplicationStateListener mListener;
|
|
|
| + /**
|
| + * Indicates whether a request to install a WebPK has started. This flag is set before
|
| + * the package name of the WebAPK is available.
|
| + */
|
| + private boolean mIsWebApkInstalling = false;
|
| +
|
| + private String mWebApkPackage;
|
| +
|
| + /**
|
| + * Indicates whether to monitor the installation of the downloaded WebAPK. Currently WebAPKs
|
| + * aren't installed by Play, so user could cancel the installation when Android installation
|
| + * dialog shows. The only way to know whether user cancels the installation is to check whether
|
| + * the WebAPK is installed when Chrome is resumed. This flag is set to true once the
|
| + * installation Intent is sent to Android System.
|
| + */
|
| + private boolean mStartMonitoringWebApkInstallation = false;
|
| +
|
| /** Overrides the PackageManager for testing. */
|
| @VisibleForTesting
|
| public static void setPackageManagerForTesting(PackageManager manager) {
|
| @@ -56,6 +77,13 @@ public class AppBannerInfoBarDelegateAndroid {
|
| @Override
|
| public void onApplicationStateChange(int newState) {
|
| if (!ApplicationStatus.hasVisibleActivities()) return;
|
| + if (mStartMonitoringWebApkInstallation
|
| + && newState == ApplicationState.HAS_RUNNING_ACTIVITIES) {
|
| + if (nativeCloseAppBannerInfobarIfNeeded(mNativePointer)) {
|
| + mStartMonitoringWebApkInstallation = false;
|
| + return;
|
| + }
|
| + }
|
| nativeUpdateInstallState(mNativePointer);
|
| }
|
| };
|
| @@ -79,10 +107,7 @@ public class AppBannerInfoBarDelegateAndroid {
|
|
|
| if (InstallerDelegate.isInstalled(packageManager, packageName)) {
|
| // Open the app.
|
| - Intent launchIntent = packageManager.getLaunchIntentForPackage(packageName);
|
| - if (launchIntent == null) return true;
|
| - context.startActivity(launchIntent);
|
| - return true;
|
| + return openApp(context, packageName);
|
| } else {
|
| // Try installing the app. If the installation was kicked off, return false to prevent
|
| // the infobar from disappearing.
|
| @@ -96,6 +121,14 @@ public class AppBannerInfoBarDelegateAndroid {
|
| }
|
| }
|
|
|
| + private boolean openApp(Context context, String packageName) {
|
| + Intent launchIntent = getPackageManager(context).getLaunchIntentForPackage(packageName);
|
| + if (launchIntent != null) {
|
| + context.startActivity(launchIntent);
|
| + }
|
| + return true;
|
| + }
|
| +
|
| private WindowAndroid.IntentCallback createIntentCallback(final AppData appData) {
|
| return new WindowAndroid.IntentCallback() {
|
| @Override
|
| @@ -129,18 +162,64 @@ public class AppBannerInfoBarDelegateAndroid {
|
| }
|
|
|
| @CalledByNative
|
| + private boolean installOrOpenWebApk(String packageName) {
|
| + mWebApkPackage = packageName;
|
| + Context context = ContextUtils.getApplicationContext();
|
| + PackageManager packageManager = getPackageManager(context);
|
| +
|
| + if (InstallerDelegate.isInstalled(packageManager, packageName)) {
|
| + // Open the WebApk.
|
| + mWebApkPackage = null;
|
| + mStartMonitoringWebApkInstallation = false;
|
| + return openApp(context, packageName);
|
| + } else {
|
| + // Try installing the WebAPK. If the installation was kicked off, return false to
|
| + // prevent the infobar from disappearing.
|
| + // Start monitoring the install.
|
| + mInstallTask = new InstallerDelegate(Looper.getMainLooper(), packageManager,
|
| + createInstallerDelegateObserver(), packageName);
|
| + mInstallTask.start();
|
| + mStartMonitoringWebApkInstallation = true;
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + @CalledByNative
|
| private void showAppDetails(Tab tab, AppData appData) {
|
| tab.getWindowAndroid().showIntent(appData.detailsIntent(), null, null);
|
| }
|
|
|
| @CalledByNative
|
| private int determineInstallState(AppData data) {
|
| + if (mIsWebApkInstalling) return AppBannerInfoBarAndroid.INSTALL_STATE_INSTALLING_WEBAPK;
|
| if (mInstallTask != null) return AppBannerInfoBarAndroid.INSTALL_STATE_INSTALLING;
|
|
|
| PackageManager pm = getPackageManager(ContextUtils.getApplicationContext());
|
| - boolean isInstalled = InstallerDelegate.isInstalled(pm, data.packageName());
|
| - return isInstalled ? AppBannerInfoBarAndroid.INSTALL_STATE_INSTALLED
|
| - : AppBannerInfoBarAndroid.INSTALL_STATE_NOT_INSTALLED;
|
| + String packageName = data != null ? data.packageName() : mWebApkPackage;
|
| +
|
| + boolean isInstalled = InstallerDelegate.isInstalled(pm, packageName);
|
| + if (!isInstalled) return AppBannerInfoBarAndroid.INSTALL_STATE_NOT_INSTALLED;
|
| + return data != null ? AppBannerInfoBarAndroid.INSTALL_STATE_INSTALLED
|
| + : AppBannerInfoBarAndroid.INSTALL_STATE_INSTALLED_WEBAPK;
|
| + }
|
| +
|
| + @CalledByNative
|
| + /** Set the flag of whether a installation process is started for the WebAPK. */
|
| + private void setWebApkInstallingState(boolean isInstalling) {
|
| + mIsWebApkInstalling = isInstalling;
|
| + }
|
| +
|
| + @CalledByNative
|
| + private static void showWebApkInstallFailureToast() {
|
| + ThreadUtils.runOnUiThread(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + Context applicationContext = ContextUtils.getApplicationContext();
|
| + Toast toast = Toast.makeText(applicationContext, R.string.fail_to_install_webapk,
|
| + Toast.LENGTH_SHORT);
|
| + toast.show();
|
| + }
|
| + });
|
| }
|
|
|
| private PackageManager getPackageManager(Context context) {
|
| @@ -153,9 +232,18 @@ public class AppBannerInfoBarDelegateAndroid {
|
| return new AppBannerInfoBarDelegateAndroid(nativePtr);
|
| }
|
|
|
| + @CalledByNative
|
| + private boolean isWebApkInstalled(String packageName) {
|
| + PackageManager packageManager = getPackageManager(ContextUtils.getApplicationContext());
|
| + boolean result = InstallerDelegate.isInstalled(packageManager, packageName);
|
| + return result;
|
| + }
|
| +
|
| private native void nativeOnInstallIntentReturned(
|
| long nativeAppBannerInfoBarDelegateAndroid, boolean isInstalling);
|
| private native void nativeOnInstallFinished(
|
| long nativeAppBannerInfoBarDelegateAndroid, boolean success);
|
| private native void nativeUpdateInstallState(long nativeAppBannerInfoBarDelegateAndroid);
|
| + private native boolean nativeCloseAppBannerInfobarIfNeeded(
|
| + long nativeAppBannerInfoBarDelegateAndroid);
|
| }
|
|
|