Index: chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java |
index fa7633e5d192a15fef52043d68a79bb7d9d46609..9555cca5dc777559d867be35b701fb5ef56bb832 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java |
@@ -5,27 +5,58 @@ |
package org.chromium.chrome.browser.webapps; |
import android.content.ActivityNotFoundException; |
-import android.content.BroadcastReceiver; |
import android.content.Context; |
import android.content.Intent; |
-import android.content.IntentFilter; |
+import android.content.pm.PackageManager; |
import android.net.Uri; |
+import android.os.Looper; |
import android.provider.Settings; |
+import org.chromium.base.ApplicationState; |
+import org.chromium.base.ApplicationStatus; |
import org.chromium.base.ContextUtils; |
import org.chromium.base.Log; |
import org.chromium.base.annotations.CalledByNative; |
import org.chromium.chrome.browser.ShortcutHelper; |
+import org.chromium.chrome.browser.banners.InstallerDelegate; |
import java.io.File; |
/** |
* Java counterpart to webapk_installer.h |
* Contains functionality to install / update WebAPKs. |
+ * This Java object is created by and owned by the native WebApkInstaller. |
*/ |
public class WebApkInstaller { |
private static final String TAG = "WebApkInstaller"; |
+ /** The WebAPK's package name. */ |
+ private String mWebApkPackageName; |
+ |
+ /** Monitors for application state changes. */ |
+ private ApplicationStatus.ApplicationStateListener mListener; |
+ |
+ /** Monitors an installation in progress. */ |
pkotwicz
2016/08/30 04:06:24
How about: "Monitors installation progress."
Xi Han
2016/08/30 17:49:29
Done.
|
+ private InstallerDelegate mInstallTask; |
+ |
+ /** Weak pointer to the native WebApkInstaller. */ |
+ private long mNativePointer; |
+ |
+ private WebApkInstaller(long nativePtr) { |
+ mNativePointer = nativePtr; |
+ } |
+ |
+ @CalledByNative |
+ private static WebApkInstaller create(long nativePtr) { |
+ return new WebApkInstaller(nativePtr); |
+ } |
+ |
+ @CalledByNative |
+ private void destroy() { |
+ ApplicationStatus.unregisterApplicationStateListener(mListener); |
+ mNativePointer = 0; |
+ } |
+ |
/** |
* Installs a WebAPK. |
* @param filePath File to install. |
@@ -34,18 +65,28 @@ public class WebApkInstaller { |
* install succeeds. |
*/ |
@CalledByNative |
- static boolean installAsyncFromNative(String filePath, String packageName) { |
+ private boolean installAsyncFromNative(String filePath, String packageName) { |
if (!installingFromUnknownSourcesAllowed()) { |
Log.e(TAG, |
"WebAPK install failed because installation from unknown sources is disabled."); |
return false; |
} |
+ mWebApkPackageName = packageName; |
+ |
+ // Start monitoring the installation. |
+ PackageManager packageManager = ContextUtils.getApplicationContext().getPackageManager(); |
+ mInstallTask = new InstallerDelegate(Looper.getMainLooper(), packageManager, |
+ createInstallerDelegateObserver(), packageName); |
+ mInstallTask.start(); |
+ // Start monitoring the application state changes. |
+ mListener = createApplicationStateListener(); |
+ ApplicationStatus.registerApplicationStateListener(mListener); |
+ |
Intent intent = new Intent(Intent.ACTION_VIEW); |
Uri fileUri = Uri.fromFile(new File(filePath)); |
intent.setDataAndType(fileUri, "application/vnd.android.package-archive"); |
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
try { |
- listenForPackageInstallation(packageName); |
ContextUtils.getApplicationContext().startActivity(intent); |
} catch (ActivityNotFoundException e) { |
return false; |
@@ -53,34 +94,27 @@ public class WebApkInstaller { |
return true; |
} |
- private static class WebApkInstallObserver extends BroadcastReceiver { |
- private final String mPackageName; |
- public WebApkInstallObserver(String packageName) { |
- mPackageName = packageName; |
- } |
- |
- private static String getPackageName(Intent intent) { |
- Uri uri = intent.getData(); |
- String pkg = uri != null ? uri.getSchemeSpecificPart() : null; |
- return pkg; |
- } |
- |
- @Override |
- public void onReceive(Context context, Intent intent) { |
- if (mPackageName.equals(getPackageName(intent))) { |
- ShortcutHelper.addWebApkShortcut(context, mPackageName); |
- context.unregisterReceiver(this); |
+ private InstallerDelegate.Observer createInstallerDelegateObserver() { |
+ return new InstallerDelegate.Observer() { |
+ @Override |
+ public void onInstallFinished(InstallerDelegate task, boolean success) { |
+ if (mInstallTask != task) return; |
+ onInstallFinishedInternal(success); |
} |
- } |
+ }; |
} |
- private static void listenForPackageInstallation(String packageName) { |
- IntentFilter iFilter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); |
- iFilter.addDataScheme("package"); |
- ContextUtils.getApplicationContext().registerReceiver( |
- new WebApkInstallObserver(packageName), iFilter); |
+ private void onInstallFinishedInternal(boolean success) { |
+ ApplicationStatus.unregisterApplicationStateListener(mListener); |
+ mInstallTask = null; |
+ if (mNativePointer != 0) { |
+ nativeOnInstallFinished(mNativePointer, success); |
+ } |
+ if (success) { |
+ ShortcutHelper.addWebApkShortcut(ContextUtils.getApplicationContext(), |
+ mWebApkPackageName); |
+ } |
} |
- |
/** |
* Updates a WebAPK. |
* @param filePath File to update. |
@@ -89,7 +123,9 @@ public class WebApkInstaller { |
* update succeeds. |
*/ |
@CalledByNative |
- private static boolean updateAsyncFromNative(String filePath, String packageName) { |
+ private boolean updateAsyncFromNative(String filePath, String packageName) { |
+ // TODO(hanxi): Calls back to C++ when the updating is complete or return a failure status |
+ // if fails. |
return false; |
} |
@@ -107,4 +143,32 @@ public class WebApkInstaller { |
return false; |
} |
} |
+ |
+ private ApplicationStatus.ApplicationStateListener createApplicationStateListener() { |
+ return new ApplicationStatus.ApplicationStateListener() { |
+ @Override |
+ public void onApplicationStateChange(int newState) { |
+ if (!ApplicationStatus.hasVisibleActivities()) return; |
+ /** |
+ * Currently WebAPKs aren't installed by Play. If user could cancel the |
pkotwicz
2016/08/30 04:06:24
How about: "... A user can cancel the installation
Xi Han
2016/08/30 17:49:29
It is better, thanks.
|
+ * installation when Android installation dialog shows, the only way to know |
+ * is to check whether the WebAPK is installed when Chrome is resumed. |
+ * The monitoring of application state changes will be removed once WebAPKs are |
+ * installed by Play. |
+ */ |
+ if (newState == ApplicationState.HAS_RUNNING_ACTIVITIES |
+ && !isWebApkInstalled(mWebApkPackageName)) { |
+ onInstallFinishedInternal(false); |
+ return; |
+ } |
+ } |
+ }; |
+ } |
+ |
+ private boolean isWebApkInstalled(String packageName) { |
+ PackageManager packageManager = ContextUtils.getApplicationContext().getPackageManager(); |
+ return InstallerDelegate.isInstalled(packageManager, packageName); |
+ } |
+ |
+ private native void nativeOnInstallFinished(long nativeWebApkInstaller, boolean success); |
} |