Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 8b5f776

Browse files
authored
Remove support for downloading dynamic patches. (#8663)
1 parent 1bcb96b commit 8b5f776

File tree

6 files changed

+15
-628
lines changed

6 files changed

+15
-628
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,6 @@ FILE: ../../../flutter/shell/platform/android/io/flutter/view/FlutterView.java
547547
FILE: ../../../flutter/shell/platform/android/io/flutter/view/ResourceCleaner.java
548548
FILE: ../../../flutter/shell/platform/android/io/flutter/view/ResourceExtractor.java
549549
FILE: ../../../flutter/shell/platform/android/io/flutter/view/ResourcePaths.java
550-
FILE: ../../../flutter/shell/platform/android/io/flutter/view/ResourceUpdater.java
551550
FILE: ../../../flutter/shell/platform/android/io/flutter/view/TextureRegistry.java
552551
FILE: ../../../flutter/shell/platform/android/io/flutter/view/VsyncWaiter.java
553552
FILE: ../../../flutter/shell/platform/android/library_loader.cc

shell/platform/android/BUILD.gn

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,6 @@ java_library("flutter_shell_java") {
167167
"io/flutter/view/ResourceCleaner.java",
168168
"io/flutter/view/ResourceExtractor.java",
169169
"io/flutter/view/ResourcePaths.java",
170-
"io/flutter/view/ResourceUpdater.java",
171170
"io/flutter/view/TextureRegistry.java",
172171
"io/flutter/view/VsyncWaiter.java",
173172
]

shell/platform/android/io/flutter/app/FlutterActivityDelegate.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import io.flutter.view.FlutterNativeView;
3333
import io.flutter.view.FlutterRunArguments;
3434
import io.flutter.view.FlutterView;
35-
import io.flutter.view.ResourceUpdater;
3635
import org.json.JSONObject;
3736

3837
import java.io.File;
@@ -213,7 +212,6 @@ public void onStart() {
213212
@Override
214213
public void onResume() {
215214
Application app = (Application) activity.getApplicationContext();
216-
FlutterMain.onResume(app);
217215
if (app instanceof FlutterApplication) {
218216
FlutterApplication flutterApp = (FlutterApplication) app;
219217
flutterApp.setCurrentActivity(activity);
@@ -354,14 +352,6 @@ private void runBundle(String appBundlePath) {
354352
if (!flutterView.getFlutterNativeView().isApplicationRunning()) {
355353
FlutterRunArguments args = new FlutterRunArguments();
356354
ArrayList<String> bundlePaths = new ArrayList<>();
357-
ResourceUpdater resourceUpdater = FlutterMain.getResourceUpdater();
358-
if (resourceUpdater != null) {
359-
File patchFile = resourceUpdater.getInstalledPatch();
360-
JSONObject manifest = resourceUpdater.readManifest(patchFile);
361-
if (resourceUpdater.validateManifest(manifest)) {
362-
bundlePaths.add(patchFile.getPath());
363-
}
364-
}
365355
bundlePaths.add(appBundlePath);
366356
args.bundlePaths = bundlePaths.toArray(new String[0]);
367357
args.entrypoint = "main";

shell/platform/android/io/flutter/view/FlutterMain.java

Lines changed: 1 addition & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ private static String fromFlutterAssets(String filePath) {
7474
private static String sFlutterAssetsDir = DEFAULT_FLUTTER_ASSETS_DIR;
7575

7676
private static boolean sInitialized = false;
77-
private static ResourceUpdater sResourceUpdater;
7877
private static ResourceExtractor sResourceExtractor;
7978
private static boolean sIsPrecompiledAsBlobs;
8079
private static boolean sIsPrecompiledAsSharedLibrary;
@@ -152,17 +151,7 @@ public static void startInitialization(Context applicationContext, Settings sett
152151
initAot(applicationContext);
153152
initResources(applicationContext);
154153

155-
if (sResourceUpdater == null) {
156-
System.loadLibrary("flutter");
157-
} else {
158-
sResourceExtractor.waitForCompletion();
159-
File lib = new File(PathUtils.getDataDirectory(applicationContext), DEFAULT_LIBRARY);
160-
if (lib.exists()) {
161-
System.load(lib.getAbsolutePath());
162-
} else {
163-
System.loadLibrary("flutter");
164-
}
165-
}
154+
System.loadLibrary("flutter");
166155

167156
// We record the initialization time using SystemClock because at the start of the
168157
// initialization we have not yet loaded the native library to call into dart_tools_api.h.
@@ -310,21 +299,6 @@ private static void initResources(Context applicationContext) {
310299
Log.e(TAG, "Unable to read application info", e);
311300
}
312301

313-
if (metaData != null && metaData.getBoolean("DynamicPatching")) {
314-
sResourceUpdater = new ResourceUpdater(context);
315-
// Also checking for ON_RESUME here since it's more efficient than waiting for actual
316-
// onResume. Even though actual onResume is imminent when the app has just restarted,
317-
// it's better to start downloading now, in parallel with the rest of initialization,
318-
// and avoid a second application restart a bit later when actual onResume happens.
319-
if (sResourceUpdater.getDownloadMode() == ResourceUpdater.DownloadMode.ON_RESTART ||
320-
sResourceUpdater.getDownloadMode() == ResourceUpdater.DownloadMode.ON_RESUME) {
321-
sResourceUpdater.startUpdateDownloadOnce();
322-
if (sResourceUpdater.getInstallMode() == ResourceUpdater.InstallMode.IMMEDIATE) {
323-
sResourceUpdater.waitForDownloadCompletion();
324-
}
325-
}
326-
}
327-
328302
sResourceExtractor = new ResourceExtractor(context);
329303

330304
sResourceExtractor
@@ -346,22 +320,9 @@ private static void initResources(Context applicationContext) {
346320
.addResource(sAotIsolateSnapshotInstr);
347321
}
348322

349-
if (sResourceUpdater != null) {
350-
sResourceExtractor
351-
.addResource(DEFAULT_LIBRARY);
352-
}
353-
354323
sResourceExtractor.start();
355324
}
356325

357-
public static void onResume(Context context) {
358-
if (sResourceUpdater != null) {
359-
if (sResourceUpdater.getDownloadMode() == ResourceUpdater.DownloadMode.ON_RESUME) {
360-
sResourceUpdater.startUpdateDownloadOnce();
361-
}
362-
}
363-
}
364-
365326
/**
366327
* Returns a list of the file names at the root of the application's asset
367328
* path.
@@ -403,15 +364,6 @@ public static String findAppBundlePath(Context applicationContext) {
403364
return appBundle.exists() ? appBundle.getPath() : null;
404365
}
405366

406-
/**
407-
* Returns the main internal interface for the dynamic patching subsystem.
408-
*
409-
* If this is null, it means that dynamic patching is disabled in this app.
410-
*/
411-
public static ResourceUpdater getResourceUpdater() {
412-
return sResourceUpdater;
413-
}
414-
415367
/**
416368
* Returns the file name for the given asset.
417369
* The returned file name can be used to access the asset in the APK

shell/platform/android/io/flutter/view/ResourceExtractor.java

Lines changed: 14 additions & 193 deletions
Original file line numberDiff line numberDiff line change
@@ -52,64 +52,26 @@ private class ExtractTask extends AsyncTask<Void, Void, Void> {
5252
protected Void doInBackground(Void... unused) {
5353
final File dataDir = new File(PathUtils.getDataDirectory(mContext));
5454

55-
ResourceUpdater resourceUpdater = FlutterMain.getResourceUpdater();
56-
if (resourceUpdater != null) {
57-
// Protect patch file from being overwritten by downloader while
58-
// it's being extracted since downloading happens asynchronously.
59-
resourceUpdater.getInstallationLock().lock();
55+
final String timestamp = checkTimestamp(dataDir);
56+
if (timestamp == null) {
57+
return null;
6058
}
6159

62-
try {
63-
if (resourceUpdater != null) {
64-
File updateFile = resourceUpdater.getDownloadedPatch();
65-
File activeFile = resourceUpdater.getInstalledPatch();
66-
67-
if (updateFile.exists()) {
68-
JSONObject manifest = resourceUpdater.readManifest(updateFile);
69-
if (resourceUpdater.validateManifest(manifest)) {
70-
// Graduate patch file as active for asset manager.
71-
if (activeFile.exists() && !activeFile.delete()) {
72-
Log.w(TAG, "Could not delete file " + activeFile);
73-
return null;
74-
}
75-
if (!updateFile.renameTo(activeFile)) {
76-
Log.w(TAG, "Could not create file " + activeFile);
77-
return null;
78-
}
79-
}
80-
}
81-
}
82-
83-
final String timestamp = checkTimestamp(dataDir);
84-
if (timestamp == null) {
85-
return null;
86-
}
87-
88-
deleteFiles();
89-
90-
if (!extractUpdate(dataDir)) {
91-
return null;
92-
}
60+
deleteFiles();
9361

94-
if (!extractAPK(dataDir)) {
95-
return null;
96-
}
62+
if (!extractAPK(dataDir)) {
63+
return null;
64+
}
9765

98-
if (timestamp != null) {
99-
try {
100-
new File(dataDir, timestamp).createNewFile();
101-
} catch (IOException e) {
102-
Log.w(TAG, "Failed to write resource timestamp");
103-
}
66+
if (timestamp != null) {
67+
try {
68+
new File(dataDir, timestamp).createNewFile();
69+
} catch (IOException e) {
70+
Log.w(TAG, "Failed to write resource timestamp");
10471
}
72+
}
10573

106-
return null;
107-
108-
} finally {
109-
if (resourceUpdater != null) {
110-
resourceUpdater.getInstallationLock().unlock();
111-
}
112-
}
74+
return null;
11375
}
11476
}
11577

@@ -213,133 +175,6 @@ private boolean extractAPK(File dataDir) {
213175
return true;
214176
}
215177

216-
/// Returns true if successfully unpacked update resources or if there is no update,
217-
/// otherwise deletes all resources and returns false.
218-
private boolean extractUpdate(File dataDir) {
219-
final AssetManager manager = mContext.getResources().getAssets();
220-
221-
ResourceUpdater resourceUpdater = FlutterMain.getResourceUpdater();
222-
if (resourceUpdater == null) {
223-
return true;
224-
}
225-
226-
File updateFile = resourceUpdater.getInstalledPatch();
227-
if (!updateFile.exists()) {
228-
return true;
229-
}
230-
231-
JSONObject manifest = resourceUpdater.readManifest(updateFile);
232-
if (!resourceUpdater.validateManifest(manifest)) {
233-
// Obsolete patch file, nothing to install.
234-
return true;
235-
}
236-
237-
ZipFile zipFile;
238-
try {
239-
zipFile = new ZipFile(updateFile);
240-
241-
} catch (IOException e) {
242-
Log.w(TAG, "Exception unpacking resources: " + e.getMessage());
243-
deleteFiles();
244-
return false;
245-
}
246-
247-
for (String asset : mResources) {
248-
String resource = null;
249-
ZipEntry entry = null;
250-
if (asset.endsWith(".so")) {
251-
// Replicate library lookup logic.
252-
for (String abi : SUPPORTED_ABIS) {
253-
resource = "lib/" + abi + "/" + asset;
254-
entry = zipFile.getEntry(resource);
255-
if (entry == null) {
256-
entry = zipFile.getEntry(resource + ".bzdiff40");
257-
if (entry == null) {
258-
continue;
259-
}
260-
}
261-
262-
// Stop after the first match.
263-
break;
264-
}
265-
}
266-
267-
if (entry == null) {
268-
resource = "assets/" + asset;
269-
entry = zipFile.getEntry(resource);
270-
if (entry == null) {
271-
entry = zipFile.getEntry(resource + ".bzdiff40");
272-
if (entry == null) {
273-
continue;
274-
}
275-
}
276-
}
277-
278-
final File output = new File(dataDir, asset);
279-
if (output.exists()) {
280-
continue;
281-
}
282-
if (output.getParentFile() != null) {
283-
output.getParentFile().mkdirs();
284-
}
285-
286-
try {
287-
if (entry.getName().endsWith(".bzdiff40")) {
288-
ByteArrayOutputStream diff = new ByteArrayOutputStream();
289-
try (InputStream is = zipFile.getInputStream(entry)) {
290-
copy(is, diff);
291-
}
292-
293-
ByteArrayOutputStream orig = new ByteArrayOutputStream();
294-
if (asset.endsWith(".so")) {
295-
ZipFile apkFile = new ZipFile(getAPKPath());
296-
if (apkFile == null) {
297-
throw new IOException("Could not find APK");
298-
}
299-
300-
ZipEntry origEntry = apkFile.getEntry(resource);
301-
if (origEntry == null) {
302-
throw new IOException("Could not find APK resource " + resource);
303-
}
304-
305-
try (InputStream is = apkFile.getInputStream(origEntry)) {
306-
copy(is, orig);
307-
}
308-
309-
} else {
310-
try (InputStream is = manager.open(asset)) {
311-
copy(is, orig);
312-
} catch (FileNotFoundException e) {
313-
throw new IOException("Could not find APK resource " + resource);
314-
}
315-
}
316-
317-
try (OutputStream os = new FileOutputStream(output)) {
318-
os.write(BSDiff.bspatch(orig.toByteArray(), diff.toByteArray()));
319-
}
320-
321-
} else {
322-
try (InputStream is = zipFile.getInputStream(entry);
323-
OutputStream os = new FileOutputStream(output)) {
324-
copy(is, os);
325-
}
326-
}
327-
328-
Log.i(TAG, "Extracted override resource " + entry.getName());
329-
330-
} catch (FileNotFoundException fnfe) {
331-
continue;
332-
333-
} catch (IOException ioe) {
334-
Log.w(TAG, "Exception unpacking resources: " + ioe.getMessage());
335-
deleteFiles();
336-
return false;
337-
}
338-
}
339-
340-
return true;
341-
}
342-
343178
// Returns null if extracted resources are found and match the current APK version
344179
// and update version if any, otherwise returns the current APK and update version.
345180
private String checkTimestamp(File dataDir) {
@@ -359,20 +194,6 @@ private String checkTimestamp(File dataDir) {
359194
String expectedTimestamp =
360195
TIMESTAMP_PREFIX + getVersionCode(packageInfo) + "-" + packageInfo.lastUpdateTime;
361196

362-
ResourceUpdater resourceUpdater = FlutterMain.getResourceUpdater();
363-
if (resourceUpdater != null) {
364-
File patchFile = resourceUpdater.getInstalledPatch();
365-
JSONObject manifest = resourceUpdater.readManifest(patchFile);
366-
if (resourceUpdater.validateManifest(manifest)) {
367-
String patchNumber = manifest.optString("patchNumber", null);
368-
if (patchNumber != null) {
369-
expectedTimestamp += "-" + patchNumber + "-" + patchFile.lastModified();
370-
} else {
371-
expectedTimestamp += "-" + patchFile.lastModified();
372-
}
373-
}
374-
}
375-
376197
final String[] existingTimestamps = getExistingTimestamps(dataDir);
377198

378199
if (existingTimestamps == null) {

0 commit comments

Comments
 (0)