Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import io.flutter.view.FlutterRunArguments;
import io.flutter.view.FlutterView;

import java.io.File;
import java.util.ArrayList;

/**
Expand Down Expand Up @@ -343,8 +344,9 @@ private void runBundle(String appBundlePath) {
if (!flutterView.getFlutterNativeView().isApplicationRunning()) {
FlutterRunArguments args = new FlutterRunArguments();
ArrayList<String> 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]);
Expand Down
9 changes: 7 additions & 2 deletions shell/platform/android/io/flutter/view/FlutterMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/**
Expand Down
31 changes: 12 additions & 19 deletions shell/platform/android/io/flutter/view/ResourceExtractor.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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();
}
}
}
Expand Down Expand Up @@ -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;
}
Expand Down
37 changes: 18 additions & 19 deletions shell/platform/android/io/flutter/view/ResourceUpdater.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,23 +58,23 @@ enum InstallMode {
IMMEDIATE
}

private static class DownloadTask extends AsyncTask<String, String, Void> {
private class DownloadTask extends AsyncTask<String, String, Void> {
@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);

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()) {
Expand Down Expand Up @@ -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;
}
}
Expand All @@ -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);
Expand All @@ -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(
Expand All @@ -168,7 +167,7 @@ public String buildUpdateDownloadURL() {
return uri.normalize().toString();
}

public DownloadMode getDownloadMode() {
DownloadMode getDownloadMode() {
Bundle metaData;
try {
metaData = context.getPackageManager().getApplicationInfo(
Expand All @@ -195,7 +194,7 @@ public DownloadMode getDownloadMode() {
}
}

public InstallMode getInstallMode() {
InstallMode getInstallMode() {
Bundle metaData;
try {
metaData = context.getPackageManager().getApplicationInfo(
Expand All @@ -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;
Expand Down