diff --git a/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java b/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java index 2a4c924c50d9d..429f43ad8ae77 100644 --- a/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java +++ b/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java @@ -33,6 +33,7 @@ import io.flutter.view.FlutterRunArguments; import io.flutter.view.FlutterView; +import java.io.File; import java.util.ArrayList; /** @@ -343,8 +344,9 @@ private void runBundle(String appBundlePath) { if (!flutterView.getFlutterNativeView().isApplicationRunning()) { FlutterRunArguments args = new FlutterRunArguments(); ArrayList bundlePaths = new ArrayList<>(); - if (FlutterMain.getUpdateInstallationPath() != null) { - bundlePaths.add(FlutterMain.getUpdateInstallationPath()); + if (FlutterMain.getResourceUpdater() != null) { + File patchFile = FlutterMain.getResourceUpdater().getPatch(); + bundlePaths.add(patchFile.getPath()); } bundlePaths.add(appBundlePath); args.bundlePaths = bundlePaths.toArray(new String[0]); diff --git a/shell/platform/android/io/flutter/view/FlutterMain.java b/shell/platform/android/io/flutter/view/FlutterMain.java index 16d1c0ec3e2d0..9b0edbeed0b9f 100644 --- a/shell/platform/android/io/flutter/view/FlutterMain.java +++ b/shell/platform/android/io/flutter/view/FlutterMain.java @@ -360,8 +360,13 @@ public static String findAppBundlePath(Context applicationContext) { return appBundle.exists() ? appBundle.getPath() : null; } - public static String getUpdateInstallationPath() { - return sResourceUpdater == null ? null : sResourceUpdater.getUpdateInstallationPath(); + /** + * Returns the main internal interface for the dynamic patching subsystem. + * + * If this is null, it means that dynamic patching is disabled in this app. + */ + public static ResourceUpdater getResourceUpdater() { + return sResourceUpdater; } /** diff --git a/shell/platform/android/io/flutter/view/ResourceExtractor.java b/shell/platform/android/io/flutter/view/ResourceExtractor.java index c28749b9e92d1..cfcae096678ba 100644 --- a/shell/platform/android/io/flutter/view/ResourceExtractor.java +++ b/shell/platform/android/io/flutter/view/ResourceExtractor.java @@ -123,17 +123,6 @@ void waitForCompletion() { } } - boolean filesMatch() { - JSONObject updateManifest = readUpdateManifest(); - if (!validateUpdateManifest(updateManifest)) { - updateManifest = null; - } - - final File dataDir = new File(PathUtils.getDataDirectory(mContext)); - final String timestamp = checkTimestamp(dataDir, updateManifest); - return (timestamp == null); - } - private String[] getExistingTimestamps(File dataDir) { return dataDir.list(new FilenameFilter() { @Override @@ -160,7 +149,6 @@ private void deleteFiles() { } } - /// Returns true if successfully unpacked APK resources, /// otherwise deletes all resources and returns false. private boolean extractAPK(File dataDir) { @@ -208,11 +196,12 @@ private boolean extractAPK(File dataDir) { /// Returns true if successfully unpacked update resources or if there is no update, /// otherwise deletes all resources and returns false. private boolean extractUpdate(File dataDir) { - if (FlutterMain.getUpdateInstallationPath() == null) { + ResourceUpdater resourceUpdater = FlutterMain.getResourceUpdater(); + if (resourceUpdater == null) { return true; } - final File updateFile = new File(FlutterMain.getUpdateInstallationPath()); + File updateFile = resourceUpdater.getPatch(); if (!updateFile.exists()) { return true; } @@ -298,11 +287,14 @@ private String checkTimestamp(File dataDir, JSONObject updateManifest) { if (!buildNumber.equals(Long.toString(getVersionCode(packageInfo)))) { Log.w(TAG, "Outdated update file for " + getVersionCode(packageInfo)); } else { - final File updateFile = new File(FlutterMain.getUpdateInstallationPath()); + ResourceUpdater resourceUpdater = FlutterMain.getResourceUpdater(); + assert resourceUpdater != null; + File patchFile = resourceUpdater.getPatch(); + assert patchFile.exists(); if (patchNumber != null) { - expectedTimestamp += "-" + patchNumber + "-" + updateFile.lastModified(); + expectedTimestamp += "-" + patchNumber + "-" + patchFile.lastModified(); } else { - expectedTimestamp += "-" + updateFile.lastModified(); + expectedTimestamp += "-" + patchFile.lastModified(); } } } @@ -365,11 +357,12 @@ private boolean validateUpdateManifest(JSONObject updateManifest) { /// Returns null if no update manifest is found. private JSONObject readUpdateManifest() { - if (FlutterMain.getUpdateInstallationPath() == null) { + ResourceUpdater resourceUpdater = FlutterMain.getResourceUpdater(); + if (resourceUpdater == null) { return null; } - File updateFile = new File(FlutterMain.getUpdateInstallationPath()); + File updateFile = resourceUpdater.getPatch(); if (!updateFile.exists()) { return null; } diff --git a/shell/platform/android/io/flutter/view/ResourceUpdater.java b/shell/platform/android/io/flutter/view/ResourceUpdater.java index 203ae18d052f7..5fef38f66f111 100644 --- a/shell/platform/android/io/flutter/view/ResourceUpdater.java +++ b/shell/platform/android/io/flutter/view/ResourceUpdater.java @@ -58,12 +58,12 @@ enum InstallMode { IMMEDIATE } - private static class DownloadTask extends AsyncTask { + private class DownloadTask extends AsyncTask { @Override - protected Void doInBackground(String... args) { + protected Void doInBackground(String... unused) { try { - URL unresolvedURL = new URL(args[0]); - File localFile = new File(args[1]); + URL unresolvedURL = new URL(buildUpdateDownloadURL()); + File localFile = getPatch(); long startMillis = new Date().getTime(); Log.i(TAG, "Checking for updates at " + unresolvedURL); @@ -71,10 +71,10 @@ protected Void doInBackground(String... args) { HttpURLConnection connection = (HttpURLConnection)unresolvedURL.openConnection(); - long lastModified = localFile.lastModified(); - if (lastModified != 0) { - Log.i(TAG, "Active update timestamp " + lastModified); - connection.setIfModifiedSince(lastModified); + long lastDownloadTime = localFile.lastModified(); + if (lastDownloadTime != 0) { + Log.i(TAG, "Active update timestamp " + lastDownloadTime); + connection.setIfModifiedSince(lastDownloadTime); } try (InputStream input = connection.getInputStream()) { @@ -108,7 +108,6 @@ protected Void doInBackground(String... args) { long totalMillis = new Date().getTime() - startMillis; Log.i(TAG, "Update downloaded in " + totalMillis / 100 / 10. + "s"); - output.flush(); return null; } } @@ -127,7 +126,7 @@ public ResourceUpdater(Context context) { this.context = context; } - public String getAPKVersion() { + private String getAPKVersion() { try { PackageManager packageManager = context.getPackageManager(); PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0); @@ -138,11 +137,11 @@ public String getAPKVersion() { } } - public String getUpdateInstallationPath() { - return context.getFilesDir().toString() + "/patch.zip"; + public File getPatch() { + return new File(context.getFilesDir().toString() + "/patch.zip"); } - public String buildUpdateDownloadURL() { + private String buildUpdateDownloadURL() { Bundle metaData; try { metaData = context.getPackageManager().getApplicationInfo( @@ -168,7 +167,7 @@ public String buildUpdateDownloadURL() { return uri.normalize().toString(); } - public DownloadMode getDownloadMode() { + DownloadMode getDownloadMode() { Bundle metaData; try { metaData = context.getPackageManager().getApplicationInfo( @@ -195,7 +194,7 @@ public DownloadMode getDownloadMode() { } } - public InstallMode getInstallMode() { + InstallMode getInstallMode() { Bundle metaData; try { metaData = context.getPackageManager().getApplicationInfo( @@ -222,21 +221,21 @@ public InstallMode getInstallMode() { } } - public void startUpdateDownloadOnce() { + void startUpdateDownloadOnce() { if (downloadTask != null ) { return; } downloadTask = new DownloadTask(); - downloadTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, - buildUpdateDownloadURL(), getUpdateInstallationPath()); + downloadTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } - public void waitForDownloadCompletion() { + void waitForDownloadCompletion() { if (downloadTask == null) { return; } try { downloadTask.get(); + downloadTask = null; } catch (CancellationException e) { Log.w(TAG, "Download cancelled: " + e.getMessage()); return;