Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(190)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegateAndroid.java

Issue 2259553002: Make AppBannerInfoBar install WebAPK. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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.ApplicationState;
14 import org.chromium.base.ApplicationStatus; 15 import org.chromium.base.ApplicationStatus;
15 import org.chromium.base.ContextUtils; 16 import org.chromium.base.ContextUtils;
17 import org.chromium.base.ThreadUtils;
16 import org.chromium.base.VisibleForTesting; 18 import org.chromium.base.VisibleForTesting;
17 import org.chromium.base.annotations.CalledByNative; 19 import org.chromium.base.annotations.CalledByNative;
18 import org.chromium.base.annotations.JNINamespace; 20 import org.chromium.base.annotations.JNINamespace;
21 import org.chromium.chrome.R;
19 import org.chromium.chrome.browser.banners.AppData; 22 import org.chromium.chrome.browser.banners.AppData;
20 import org.chromium.chrome.browser.banners.InstallerDelegate; 23 import org.chromium.chrome.browser.banners.InstallerDelegate;
21 import org.chromium.chrome.browser.tab.Tab; 24 import org.chromium.chrome.browser.tab.Tab;
22 import org.chromium.ui.base.WindowAndroid; 25 import org.chromium.ui.base.WindowAndroid;
26 import org.chromium.ui.widget.Toast;
23 27
24 /** 28 /**
25 * Handles the promotion and installation of an app specified by the current web page. This Java 29 * 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. 30 * object is created by and owned by the native AppBannerInfoBarDelegateAndroid.
27 */ 31 */
28 @JNINamespace("banners") 32 @JNINamespace("banners")
29 public class AppBannerInfoBarDelegateAndroid { 33 public class AppBannerInfoBarDelegateAndroid {
30 /** PackageManager to use in place of the real one. */ 34 /** PackageManager to use in place of the real one. */
31 private static PackageManager sPackageManagerForTests; 35 private static PackageManager sPackageManagerForTests;
32 36
33 /** Weak pointer to the native AppBannerInfoBarDelegateAndroid. */ 37 /** Weak pointer to the native AppBannerInfoBarDelegateAndroid. */
34 private long mNativePointer; 38 private long mNativePointer;
35 39
36 /** Monitors an installation in progress. */ 40 /** Monitors an installation in progress. */
37 private InstallerDelegate mInstallTask; 41 private InstallerDelegate mInstallTask;
38 42
39 /** Monitors for application state changes. */ 43 /** Monitors for application state changes. */
40 private final ApplicationStatus.ApplicationStateListener mListener; 44 private final ApplicationStatus.ApplicationStateListener mListener;
41 45
46 /**
47 * Indicates whether a request to install a WebPK has started. This flag is set before
48 * the package name of the WebAPK is available.
49 */
50 private boolean mIsWebApkInstalling = false;
51
52 private String mWebApkPackage;
53
54 /**
55 * Indicates whether to monitor the installation of the downloaded WebAPK. C urrently WebAPKs
56 * aren't installed by Play, so user could cancel the installation when Andr oid installation
57 * dialog shows. The only way to know whether user cancels the installation is to check whether
58 * the WebAPK is installed when Chrome is resumed. This flag is set to true once the
59 * installation Intent is sent to Android System.
60 */
61 private boolean mStartMonitoringWebApkInstallation = false;
62
42 /** Overrides the PackageManager for testing. */ 63 /** Overrides the PackageManager for testing. */
43 @VisibleForTesting 64 @VisibleForTesting
44 public static void setPackageManagerForTesting(PackageManager manager) { 65 public static void setPackageManagerForTesting(PackageManager manager) {
45 sPackageManagerForTests = manager; 66 sPackageManagerForTests = manager;
46 } 67 }
47 68
48 private AppBannerInfoBarDelegateAndroid(long nativePtr) { 69 private AppBannerInfoBarDelegateAndroid(long nativePtr) {
49 mNativePointer = nativePtr; 70 mNativePointer = nativePtr;
50 mListener = createApplicationStateListener(); 71 mListener = createApplicationStateListener();
51 ApplicationStatus.registerApplicationStateListener(mListener); 72 ApplicationStatus.registerApplicationStateListener(mListener);
52 } 73 }
53 74
54 private ApplicationStatus.ApplicationStateListener createApplicationStateLis tener() { 75 private ApplicationStatus.ApplicationStateListener createApplicationStateLis tener() {
55 return new ApplicationStatus.ApplicationStateListener() { 76 return new ApplicationStatus.ApplicationStateListener() {
56 @Override 77 @Override
57 public void onApplicationStateChange(int newState) { 78 public void onApplicationStateChange(int newState) {
58 if (!ApplicationStatus.hasVisibleActivities()) return; 79 if (!ApplicationStatus.hasVisibleActivities()) return;
80 if (mStartMonitoringWebApkInstallation
81 && newState == ApplicationState.HAS_RUNNING_ACTIVITIES) {
82 if (nativeCloseAppBannerInfobarIfNeeded(mNativePointer)) {
83 mStartMonitoringWebApkInstallation = false;
84 return;
85 }
86 }
59 nativeUpdateInstallState(mNativePointer); 87 nativeUpdateInstallState(mNativePointer);
60 } 88 }
61 }; 89 };
62 } 90 }
63 91
64 @CalledByNative 92 @CalledByNative
65 private void destroy() { 93 private void destroy() {
66 if (mInstallTask != null) { 94 if (mInstallTask != null) {
67 mInstallTask.cancel(); 95 mInstallTask.cancel();
68 mInstallTask = null; 96 mInstallTask = null;
69 } 97 }
70 ApplicationStatus.unregisterApplicationStateListener(mListener); 98 ApplicationStatus.unregisterApplicationStateListener(mListener);
71 mNativePointer = 0; 99 mNativePointer = 0;
72 } 100 }
73 101
74 @CalledByNative 102 @CalledByNative
75 private boolean installOrOpenNativeApp(Tab tab, AppData appData, String refe rrer) { 103 private boolean installOrOpenNativeApp(Tab tab, AppData appData, String refe rrer) {
76 Context context = ContextUtils.getApplicationContext(); 104 Context context = ContextUtils.getApplicationContext();
77 String packageName = appData.packageName(); 105 String packageName = appData.packageName();
78 PackageManager packageManager = getPackageManager(context); 106 PackageManager packageManager = getPackageManager(context);
79 107
80 if (InstallerDelegate.isInstalled(packageManager, packageName)) { 108 if (InstallerDelegate.isInstalled(packageManager, packageName)) {
81 // Open the app. 109 // Open the app.
82 Intent launchIntent = packageManager.getLaunchIntentForPackage(packa geName); 110 return openApp(context, packageName);
83 if (launchIntent == null) return true;
84 context.startActivity(launchIntent);
85 return true;
86 } else { 111 } else {
87 // Try installing the app. If the installation was kicked off, retu rn false to prevent 112 // Try installing the app. If the installation was kicked off, retu rn false to prevent
88 // the infobar from disappearing. 113 // the infobar from disappearing.
89 // The supplied referrer is the URL of the page requesting the nativ e app banner. It 114 // 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 115 // 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. 116 // to the installation intent as Intent.EXTRA_REFERRER.
92 Intent installIntent = appData.installIntent(); 117 Intent installIntent = appData.installIntent();
93 if (referrer.length() > 0) installIntent.putExtra(Intent.EXTRA_REFER RER, referrer); 118 if (referrer.length() > 0) installIntent.putExtra(Intent.EXTRA_REFER RER, referrer);
94 return !tab.getWindowAndroid().showIntent( 119 return !tab.getWindowAndroid().showIntent(
95 installIntent, createIntentCallback(appData), null); 120 installIntent, createIntentCallback(appData), null);
96 } 121 }
97 } 122 }
98 123
124 private boolean openApp(Context context, String packageName) {
125 Intent launchIntent = getPackageManager(context).getLaunchIntentForPacka ge(packageName);
126 if (launchIntent != null) {
127 context.startActivity(launchIntent);
128 }
129 return true;
130 }
131
99 private WindowAndroid.IntentCallback createIntentCallback(final AppData appD ata) { 132 private WindowAndroid.IntentCallback createIntentCallback(final AppData appD ata) {
100 return new WindowAndroid.IntentCallback() { 133 return new WindowAndroid.IntentCallback() {
101 @Override 134 @Override
102 public void onIntentCompleted(WindowAndroid window, int resultCode, 135 public void onIntentCompleted(WindowAndroid window, int resultCode,
103 ContentResolver contentResolver, Intent data) { 136 ContentResolver contentResolver, Intent data) {
104 boolean isInstalling = resultCode == Activity.RESULT_OK; 137 boolean isInstalling = resultCode == Activity.RESULT_OK;
105 if (isInstalling) { 138 if (isInstalling) {
106 // Start monitoring the install. 139 // Start monitoring the install.
107 PackageManager pm = 140 PackageManager pm =
108 getPackageManager(ContextUtils.getApplicationContext ()); 141 getPackageManager(ContextUtils.getApplicationContext ());
(...skipping 13 matching lines...) Expand all
122 @Override 155 @Override
123 public void onInstallFinished(InstallerDelegate task, boolean succes s) { 156 public void onInstallFinished(InstallerDelegate task, boolean succes s) {
124 if (mInstallTask != task) return; 157 if (mInstallTask != task) return;
125 mInstallTask = null; 158 mInstallTask = null;
126 nativeOnInstallFinished(mNativePointer, success); 159 nativeOnInstallFinished(mNativePointer, success);
127 } 160 }
128 }; 161 };
129 } 162 }
130 163
131 @CalledByNative 164 @CalledByNative
165 private boolean installOrOpenWebApk(String packageName) {
166 mWebApkPackage = packageName;
167 Context context = ContextUtils.getApplicationContext();
168 PackageManager packageManager = getPackageManager(context);
169
170 if (InstallerDelegate.isInstalled(packageManager, packageName)) {
171 // Open the WebApk.
172 mWebApkPackage = null;
173 mStartMonitoringWebApkInstallation = false;
174 return openApp(context, packageName);
175 } else {
176 // Try installing the WebAPK. If the installation was kicked off, r eturn false to
177 // prevent the infobar from disappearing.
178 // Start monitoring the install.
179 mInstallTask = new InstallerDelegate(Looper.getMainLooper(), package Manager,
180 createInstallerDelegateObserver(), packageName);
181 mInstallTask.start();
182 mStartMonitoringWebApkInstallation = true;
183 return false;
184 }
185 }
186
187 @CalledByNative
132 private void showAppDetails(Tab tab, AppData appData) { 188 private void showAppDetails(Tab tab, AppData appData) {
133 tab.getWindowAndroid().showIntent(appData.detailsIntent(), null, null); 189 tab.getWindowAndroid().showIntent(appData.detailsIntent(), null, null);
134 } 190 }
135 191
136 @CalledByNative 192 @CalledByNative
137 private int determineInstallState(AppData data) { 193 private int determineInstallState(AppData data) {
194 if (mIsWebApkInstalling) return AppBannerInfoBarAndroid.INSTALL_STATE_IN STALLING_WEBAPK;
138 if (mInstallTask != null) return AppBannerInfoBarAndroid.INSTALL_STATE_I NSTALLING; 195 if (mInstallTask != null) return AppBannerInfoBarAndroid.INSTALL_STATE_I NSTALLING;
139 196
140 PackageManager pm = getPackageManager(ContextUtils.getApplicationContext ()); 197 PackageManager pm = getPackageManager(ContextUtils.getApplicationContext ());
141 boolean isInstalled = InstallerDelegate.isInstalled(pm, data.packageName ()); 198 String packageName = data != null ? data.packageName() : mWebApkPackage;
142 return isInstalled ? AppBannerInfoBarAndroid.INSTALL_STATE_INSTALLED 199
143 : AppBannerInfoBarAndroid.INSTALL_STATE_NOT_INSTALLED; 200 boolean isInstalled = InstallerDelegate.isInstalled(pm, packageName);
201 if (!isInstalled) return AppBannerInfoBarAndroid.INSTALL_STATE_NOT_INSTA LLED;
202 return data != null ? AppBannerInfoBarAndroid.INSTALL_STATE_INSTALLED
203 : AppBannerInfoBarAndroid.INSTALL_STATE_INSTALLED_WEBAPK;
204 }
205
206 @CalledByNative
207 /** Set the flag of whether a installation process is started for the WebAPK . */
208 private void setWebApkInstallingState(boolean isInstalling) {
209 mIsWebApkInstalling = isInstalling;
210 }
211
212 @CalledByNative
213 private static void showWebApkInstallFailureToast() {
214 ThreadUtils.runOnUiThread(new Runnable() {
215 @Override
216 public void run() {
217 Context applicationContext = ContextUtils.getApplicationContext( );
218 Toast toast = Toast.makeText(applicationContext, R.string.fail_t o_install_webapk,
219 Toast.LENGTH_SHORT);
220 toast.show();
221 }
222 });
144 } 223 }
145 224
146 private PackageManager getPackageManager(Context context) { 225 private PackageManager getPackageManager(Context context) {
147 if (sPackageManagerForTests != null) return sPackageManagerForTests; 226 if (sPackageManagerForTests != null) return sPackageManagerForTests;
148 return context.getPackageManager(); 227 return context.getPackageManager();
149 } 228 }
150 229
151 @CalledByNative 230 @CalledByNative
152 private static AppBannerInfoBarDelegateAndroid create(long nativePtr) { 231 private static AppBannerInfoBarDelegateAndroid create(long nativePtr) {
153 return new AppBannerInfoBarDelegateAndroid(nativePtr); 232 return new AppBannerInfoBarDelegateAndroid(nativePtr);
154 } 233 }
155 234
235 @CalledByNative
236 private boolean isWebApkInstalled(String packageName) {
237 PackageManager packageManager = getPackageManager(ContextUtils.getApplic ationContext());
238 boolean result = InstallerDelegate.isInstalled(packageManager, packageNa me);
239 return result;
240 }
241
156 private native void nativeOnInstallIntentReturned( 242 private native void nativeOnInstallIntentReturned(
157 long nativeAppBannerInfoBarDelegateAndroid, boolean isInstalling); 243 long nativeAppBannerInfoBarDelegateAndroid, boolean isInstalling);
158 private native void nativeOnInstallFinished( 244 private native void nativeOnInstallFinished(
159 long nativeAppBannerInfoBarDelegateAndroid, boolean success); 245 long nativeAppBannerInfoBarDelegateAndroid, boolean success);
160 private native void nativeUpdateInstallState(long nativeAppBannerInfoBarDele gateAndroid); 246 private native void nativeUpdateInstallState(long nativeAppBannerInfoBarDele gateAndroid);
247 private native boolean nativeCloseAppBannerInfobarIfNeeded(
248 long nativeAppBannerInfoBarDelegateAndroid);
161 } 249 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698