Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.infobar; | 5 package org.chromium.chrome.browser.infobar; |
| 6 | 6 |
| 7 import android.app.Activity; | 7 import android.app.Activity; |
| 8 import android.content.ContentResolver; | 8 import android.content.ContentResolver; |
| 9 import android.content.Context; | 9 import android.content.Context; |
| 10 import android.content.Intent; | 10 import android.content.Intent; |
| 11 import android.content.pm.PackageManager; | 11 import android.content.pm.PackageManager; |
| 12 import android.os.Looper; | 12 import android.os.Looper; |
| 13 | 13 |
| 14 import org.chromium.base.ApplicationStatus; | 14 import org.chromium.base.ApplicationStatus; |
| 15 import org.chromium.base.ContextUtils; | 15 import org.chromium.base.ContextUtils; |
| 16 import org.chromium.base.ThreadUtils; | |
| 16 import org.chromium.base.VisibleForTesting; | 17 import org.chromium.base.VisibleForTesting; |
| 17 import org.chromium.base.annotations.CalledByNative; | 18 import org.chromium.base.annotations.CalledByNative; |
| 18 import org.chromium.base.annotations.JNINamespace; | 19 import org.chromium.base.annotations.JNINamespace; |
| 20 import org.chromium.chrome.R; | |
| 19 import org.chromium.chrome.browser.banners.AppData; | 21 import org.chromium.chrome.browser.banners.AppData; |
| 20 import org.chromium.chrome.browser.banners.InstallerDelegate; | 22 import org.chromium.chrome.browser.banners.InstallerDelegate; |
| 21 import org.chromium.chrome.browser.tab.Tab; | 23 import org.chromium.chrome.browser.tab.Tab; |
| 22 import org.chromium.ui.base.WindowAndroid; | 24 import org.chromium.ui.base.WindowAndroid; |
| 25 import org.chromium.ui.widget.Toast; | |
| 23 | 26 |
| 24 /** | 27 /** |
| 25 * Handles the promotion and installation of an app specified by the current web page. This Java | 28 * Handles the promotion and installation of an app specified by the current web page. This Java |
| 26 * object is created by and owned by the native AppBannerInfoBarDelegateAndroid. | 29 * object is created by and owned by the native AppBannerInfoBarDelegateAndroid. |
| 27 */ | 30 */ |
| 28 @JNINamespace("banners") | 31 @JNINamespace("banners") |
| 29 public class AppBannerInfoBarDelegateAndroid { | 32 public class AppBannerInfoBarDelegateAndroid { |
| 30 /** PackageManager to use in place of the real one. */ | 33 /** PackageManager to use in place of the real one. */ |
| 31 private static PackageManager sPackageManagerForTests; | 34 private static PackageManager sPackageManagerForTests; |
| 32 | 35 |
| 33 /** Weak pointer to the native AppBannerInfoBarDelegateAndroid. */ | 36 /** Weak pointer to the native AppBannerInfoBarDelegateAndroid. */ |
| 34 private long mNativePointer; | 37 private long mNativePointer; |
| 35 | 38 |
| 36 /** Monitors an installation in progress. */ | 39 /** Monitors an installation in progress. */ |
| 37 private InstallerDelegate mInstallTask; | 40 private InstallerDelegate mInstallTask; |
| 38 | 41 |
| 39 /** Monitors for application state changes. */ | 42 /** Monitors for application state changes. */ |
| 40 private final ApplicationStatus.ApplicationStateListener mListener; | 43 private final ApplicationStatus.ApplicationStateListener mListener; |
| 41 | 44 |
| 45 /** | |
| 46 * Indicates whether a request to install a WebPK has started. This flag is set before | |
| 47 * the package name of the WebAPK is available. | |
| 48 */ | |
| 49 private boolean mIsWebApkInstalling = false; | |
| 50 | |
| 51 /** The package name of the WebAPK. */ | |
| 52 private String mWebApkPackage; | |
| 53 | |
| 54 /** Indicates whether the banner is for installing a WebAPK. */ | |
| 55 private boolean mIsWebApk; | |
| 56 | |
| 42 /** Overrides the PackageManager for testing. */ | 57 /** Overrides the PackageManager for testing. */ |
| 43 @VisibleForTesting | 58 @VisibleForTesting |
| 44 public static void setPackageManagerForTesting(PackageManager manager) { | 59 public static void setPackageManagerForTesting(PackageManager manager) { |
| 45 sPackageManagerForTests = manager; | 60 sPackageManagerForTests = manager; |
| 46 } | 61 } |
| 47 | 62 |
| 48 private AppBannerInfoBarDelegateAndroid(long nativePtr) { | 63 private AppBannerInfoBarDelegateAndroid(long nativePtr, boolean isWebApk) { |
| 49 mNativePointer = nativePtr; | 64 mNativePointer = nativePtr; |
| 50 mListener = createApplicationStateListener(); | 65 mListener = createApplicationStateListener(); |
| 51 ApplicationStatus.registerApplicationStateListener(mListener); | 66 ApplicationStatus.registerApplicationStateListener(mListener); |
| 67 mIsWebApk = isWebApk; | |
|
pkotwicz
2016/08/25 22:23:15
We don't seem to use |mIsWebApk| anymore.
Xi Han
2016/08/26 17:04:17
Good catch, removed.
| |
| 52 } | 68 } |
| 53 | 69 |
| 54 private ApplicationStatus.ApplicationStateListener createApplicationStateLis tener() { | 70 private ApplicationStatus.ApplicationStateListener createApplicationStateLis tener() { |
| 55 return new ApplicationStatus.ApplicationStateListener() { | 71 return new ApplicationStatus.ApplicationStateListener() { |
| 56 @Override | 72 @Override |
| 57 public void onApplicationStateChange(int newState) { | 73 public void onApplicationStateChange(int newState) { |
| 58 if (!ApplicationStatus.hasVisibleActivities()) return; | 74 if (!ApplicationStatus.hasVisibleActivities()) return; |
| 59 nativeUpdateInstallState(mNativePointer); | 75 nativeUpdateInstallState(mNativePointer); |
| 60 } | 76 } |
| 61 }; | 77 }; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 72 } | 88 } |
| 73 | 89 |
| 74 @CalledByNative | 90 @CalledByNative |
| 75 private boolean installOrOpenNativeApp(Tab tab, AppData appData, String refe rrer) { | 91 private boolean installOrOpenNativeApp(Tab tab, AppData appData, String refe rrer) { |
| 76 Context context = ContextUtils.getApplicationContext(); | 92 Context context = ContextUtils.getApplicationContext(); |
| 77 String packageName = appData.packageName(); | 93 String packageName = appData.packageName(); |
| 78 PackageManager packageManager = getPackageManager(context); | 94 PackageManager packageManager = getPackageManager(context); |
| 79 | 95 |
| 80 if (InstallerDelegate.isInstalled(packageManager, packageName)) { | 96 if (InstallerDelegate.isInstalled(packageManager, packageName)) { |
| 81 // Open the app. | 97 // Open the app. |
| 82 Intent launchIntent = packageManager.getLaunchIntentForPackage(packa geName); | 98 return openApp(context, packageName); |
| 83 if (launchIntent == null) return true; | |
| 84 context.startActivity(launchIntent); | |
| 85 return true; | |
| 86 } else { | 99 } else { |
| 87 // Try installing the app. If the installation was kicked off, retu rn false to prevent | 100 // Try installing the app. If the installation was kicked off, retu rn false to prevent |
| 88 // the infobar from disappearing. | 101 // the infobar from disappearing. |
| 89 // The supplied referrer is the URL of the page requesting the nativ e app banner. It | 102 // The supplied referrer is the URL of the page requesting the nativ e app banner. It |
| 90 // may be empty depending on that page's referrer policy. If it is n on-empty, attach it | 103 // may be empty depending on that page's referrer policy. If it is n on-empty, attach it |
| 91 // to the installation intent as Intent.EXTRA_REFERRER. | 104 // to the installation intent as Intent.EXTRA_REFERRER. |
| 92 Intent installIntent = appData.installIntent(); | 105 Intent installIntent = appData.installIntent(); |
| 93 if (referrer.length() > 0) installIntent.putExtra(Intent.EXTRA_REFER RER, referrer); | 106 if (referrer.length() > 0) installIntent.putExtra(Intent.EXTRA_REFER RER, referrer); |
| 94 return !tab.getWindowAndroid().showIntent( | 107 return !tab.getWindowAndroid().showIntent( |
| 95 installIntent, createIntentCallback(appData), null); | 108 installIntent, createIntentCallback(appData), null); |
| 96 } | 109 } |
| 97 } | 110 } |
| 98 | 111 |
| 112 private boolean openApp(Context context, String packageName) { | |
|
pkotwicz
2016/08/25 22:23:15
This function always returns true. Can it be void
Xi Han
2016/08/26 17:04:17
Done.
| |
| 113 Intent launchIntent = getPackageManager(context).getLaunchIntentForPacka ge(packageName); | |
| 114 if (launchIntent != null) { | |
|
dominickn
2016/08/25 04:25:56
Nit: make this a single line if statement.
Xi Han
2016/08/26 17:04:17
Done.
| |
| 115 context.startActivity(launchIntent); | |
| 116 } | |
| 117 return true; | |
| 118 } | |
| 119 | |
| 99 private WindowAndroid.IntentCallback createIntentCallback(final AppData appD ata) { | 120 private WindowAndroid.IntentCallback createIntentCallback(final AppData appD ata) { |
| 100 return new WindowAndroid.IntentCallback() { | 121 return new WindowAndroid.IntentCallback() { |
| 101 @Override | 122 @Override |
| 102 public void onIntentCompleted(WindowAndroid window, int resultCode, | 123 public void onIntentCompleted(WindowAndroid window, int resultCode, |
| 103 ContentResolver contentResolver, Intent data) { | 124 ContentResolver contentResolver, Intent data) { |
| 104 boolean isInstalling = resultCode == Activity.RESULT_OK; | 125 boolean isInstalling = resultCode == Activity.RESULT_OK; |
| 105 if (isInstalling) { | 126 if (isInstalling) { |
| 106 // Start monitoring the install. | 127 // Start monitoring the install. |
| 107 PackageManager pm = | 128 PackageManager pm = |
| 108 getPackageManager(ContextUtils.getApplicationContext ()); | 129 getPackageManager(ContextUtils.getApplicationContext ()); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 122 @Override | 143 @Override |
| 123 public void onInstallFinished(InstallerDelegate task, boolean succes s) { | 144 public void onInstallFinished(InstallerDelegate task, boolean succes s) { |
| 124 if (mInstallTask != task) return; | 145 if (mInstallTask != task) return; |
| 125 mInstallTask = null; | 146 mInstallTask = null; |
| 126 nativeOnInstallFinished(mNativePointer, success); | 147 nativeOnInstallFinished(mNativePointer, success); |
| 127 } | 148 } |
| 128 }; | 149 }; |
| 129 } | 150 } |
| 130 | 151 |
| 131 @CalledByNative | 152 @CalledByNative |
| 153 private boolean openWebApk(String packageName) { | |
| 154 Context context = ContextUtils.getApplicationContext(); | |
| 155 PackageManager packageManager = getPackageManager(context); | |
| 156 | |
| 157 if (InstallerDelegate.isInstalled(packageManager, packageName)) { | |
| 158 // Open the WebApk. | |
|
dominickn
2016/08/25 04:25:56
Nit: remove this redundant comment
Xi Han
2016/08/26 17:04:17
Done.
| |
| 159 mWebApkPackage = null; | |
| 160 return openApp(context, packageName); | |
| 161 } | |
| 162 return true; | |
| 163 } | |
| 164 | |
| 165 @CalledByNative | |
| 132 private void showAppDetails(Tab tab, AppData appData) { | 166 private void showAppDetails(Tab tab, AppData appData) { |
| 133 tab.getWindowAndroid().showIntent(appData.detailsIntent(), null, null); | 167 tab.getWindowAndroid().showIntent(appData.detailsIntent(), null, null); |
| 134 } | 168 } |
| 135 | 169 |
| 136 @CalledByNative | 170 @CalledByNative |
| 137 private int determineInstallState(AppData data) { | 171 private int determineInstallState(AppData data) { |
| 138 if (mInstallTask != null) return AppBannerInfoBarAndroid.INSTALL_STATE_I NSTALLING; | 172 if (mInstallTask != null || mIsWebApkInstalling) { |
| 173 return AppBannerInfoBarAndroid.INSTALL_STATE_INSTALLING; | |
| 174 } | |
| 139 | 175 |
| 140 PackageManager pm = getPackageManager(ContextUtils.getApplicationContext ()); | 176 PackageManager pm = getPackageManager(ContextUtils.getApplicationContext ()); |
| 141 boolean isInstalled = InstallerDelegate.isInstalled(pm, data.packageName ()); | 177 String packageName = data != null ? data.packageName() : mWebApkPackage; |
|
dominickn
2016/08/25 04:25:56
Nit: brackets around the conditional
Xi Han
2016/08/26 17:04:17
Done.
| |
| 178 boolean isInstalled = InstallerDelegate.isInstalled(pm, packageName); | |
| 142 return isInstalled ? AppBannerInfoBarAndroid.INSTALL_STATE_INSTALLED | 179 return isInstalled ? AppBannerInfoBarAndroid.INSTALL_STATE_INSTALLED |
| 143 : AppBannerInfoBarAndroid.INSTALL_STATE_NOT_INSTALLED; | 180 : AppBannerInfoBarAndroid.INSTALL_STATE_NOT_INSTALLED; |
| 181 } | |
| 182 | |
| 183 @CalledByNative | |
| 184 /** Set the flag of whether a installation process is started for the WebAPK . */ | |
| 185 private void setWebApkInstallingState(boolean isInstalling) { | |
| 186 mIsWebApkInstalling = isInstalling; | |
| 187 } | |
| 188 | |
| 189 @CalledByNative | |
| 190 /** Sets the WebAPK package name. */ | |
| 191 private void setWebApkPackageName(String webApkPackage) { | |
| 192 mWebApkPackage = webApkPackage; | |
| 193 } | |
| 194 | |
| 195 @CalledByNative | |
| 196 private static void showWebApkInstallFailureToast() { | |
| 197 ThreadUtils.runOnUiThread(new Runnable() { | |
| 198 @Override | |
| 199 public void run() { | |
| 200 Context applicationContext = ContextUtils.getApplicationContext( ); | |
| 201 Toast toast = Toast.makeText(applicationContext, R.string.fail_t o_install_webapk, | |
| 202 Toast.LENGTH_SHORT); | |
| 203 toast.show(); | |
| 204 } | |
| 205 }); | |
| 144 } | 206 } |
| 145 | 207 |
| 146 private PackageManager getPackageManager(Context context) { | 208 private PackageManager getPackageManager(Context context) { |
| 147 if (sPackageManagerForTests != null) return sPackageManagerForTests; | 209 if (sPackageManagerForTests != null) return sPackageManagerForTests; |
| 148 return context.getPackageManager(); | 210 return context.getPackageManager(); |
| 149 } | 211 } |
| 150 | 212 |
| 151 @CalledByNative | 213 @CalledByNative |
| 152 private static AppBannerInfoBarDelegateAndroid create(long nativePtr) { | 214 private static AppBannerInfoBarDelegateAndroid create(long nativePtr, boolea n isWebApk) { |
| 153 return new AppBannerInfoBarDelegateAndroid(nativePtr); | 215 return new AppBannerInfoBarDelegateAndroid(nativePtr, isWebApk); |
| 154 } | 216 } |
| 155 | 217 |
| 156 private native void nativeOnInstallIntentReturned( | 218 private native void nativeOnInstallIntentReturned( |
| 157 long nativeAppBannerInfoBarDelegateAndroid, boolean isInstalling); | 219 long nativeAppBannerInfoBarDelegateAndroid, boolean isInstalling); |
| 158 private native void nativeOnInstallFinished( | 220 private native void nativeOnInstallFinished( |
| 159 long nativeAppBannerInfoBarDelegateAndroid, boolean success); | 221 long nativeAppBannerInfoBarDelegateAndroid, boolean success); |
| 160 private native void nativeUpdateInstallState(long nativeAppBannerInfoBarDele gateAndroid); | 222 private native void nativeUpdateInstallState(long nativeAppBannerInfoBarDele gateAndroid); |
| 161 } | 223 } |
| OLD | NEW |