1111import android .os .AsyncTask ;
1212import android .os .Build ;
1313import android .util .Log ;
14+ import io .flutter .util .BSDiff ;
1415import io .flutter .util .PathUtils ;
1516import org .json .JSONObject ;
1617
1920import java .util .HashSet ;
2021import java .util .concurrent .CancellationException ;
2122import java .util .concurrent .ExecutionException ;
23+ import java .util .zip .GZIPInputStream ;
2224import java .util .zip .ZipEntry ;
2325import java .util .zip .ZipFile ;
2426
@@ -29,8 +31,6 @@ class ResourceExtractor {
2931 private static final String TAG = "ResourceExtractor" ;
3032 private static final String TIMESTAMP_PREFIX = "res_timestamp-" ;
3133
32- private static final int BUFFER_SIZE = 16 * 1024 ;
33-
3434 @ SuppressWarnings ("deprecation" )
3535 static long getVersionCode (PackageInfo packageInfo ) {
3636 if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .P ) {
@@ -177,7 +177,6 @@ private void deleteFiles() {
177177 private boolean extractAPK (File dataDir ) {
178178 final AssetManager manager = mContext .getResources ().getAssets ();
179179
180- byte [] buffer = null ;
181180 for (String asset : mResources ) {
182181 try {
183182 final File output = new File (dataDir , asset );
@@ -190,19 +189,11 @@ private boolean extractAPK(File dataDir) {
190189
191190 try (InputStream is = manager .open (asset );
192191 OutputStream os = new FileOutputStream (output )) {
193- if (buffer == null ) {
194- buffer = new byte [BUFFER_SIZE ];
195- }
196-
197- int count = 0 ;
198- while ((count = is .read (buffer , 0 , BUFFER_SIZE )) != -1 ) {
199- os .write (buffer , 0 , count );
200- }
201-
202- os .flush ();
203- Log .i (TAG , "Extracted baseline resource " + asset );
192+ copy (is , os );
204193 }
205194
195+ Log .i (TAG , "Extracted baseline resource " + asset );
196+
206197 } catch (FileNotFoundException fnfe ) {
207198 continue ;
208199
@@ -219,6 +210,8 @@ private boolean extractAPK(File dataDir) {
219210 /// Returns true if successfully unpacked update resources or if there is no update,
220211 /// otherwise deletes all resources and returns false.
221212 private boolean extractUpdate (File dataDir ) {
213+ final AssetManager manager = mContext .getResources ().getAssets ();
214+
222215 ResourceUpdater resourceUpdater = FlutterMain .getResourceUpdater ();
223216 if (resourceUpdater == null ) {
224217 return true ;
@@ -245,11 +238,15 @@ private boolean extractUpdate(File dataDir) {
245238 return false ;
246239 }
247240
248- byte [] buffer = null ;
249241 for (String asset : mResources ) {
242+ boolean useDiff = false ;
250243 ZipEntry entry = zipFile .getEntry (asset );
251244 if (entry == null ) {
252- continue ;
245+ useDiff = true ;
246+ entry = zipFile .getEntry (asset + ".bzdiff40" );
247+ if (entry == null ) {
248+ continue ;
249+ }
253250 }
254251
255252 final File output = new File (dataDir , asset );
@@ -260,18 +257,29 @@ private boolean extractUpdate(File dataDir) {
260257 output .getParentFile ().mkdirs ();
261258 }
262259
263- try (InputStream is = zipFile .getInputStream (entry );
264- OutputStream os = new FileOutputStream (output )) {
265- if (buffer == null ) {
266- buffer = new byte [BUFFER_SIZE ];
267- }
260+ try {
261+ if (useDiff ) {
262+ ByteArrayOutputStream diff = new ByteArrayOutputStream ();
263+ try (InputStream is = zipFile .getInputStream (entry )) {
264+ copy (is , diff );
265+ }
266+
267+ ByteArrayOutputStream orig = new ByteArrayOutputStream ();
268+ try (InputStream is = manager .open (asset )) {
269+ copy (is , orig );
270+ }
271+
272+ try (OutputStream os = new FileOutputStream (output )) {
273+ os .write (BSDiff .bspatch (orig .toByteArray (), diff .toByteArray ()));
274+ }
268275
269- int count = 0 ;
270- while ((count = is .read (buffer , 0 , BUFFER_SIZE )) != -1 ) {
271- os .write (buffer , 0 , count );
276+ } else {
277+ try (InputStream is = zipFile .getInputStream (entry );
278+ OutputStream os = new FileOutputStream (output )) {
279+ copy (is , os );
280+ }
272281 }
273282
274- os .flush ();
275283 Log .i (TAG , "Extracted override resource " + asset );
276284
277285 } catch (FileNotFoundException fnfe ) {
@@ -339,4 +347,11 @@ private String checkTimestamp(File dataDir) {
339347
340348 return null ;
341349 }
350+
351+ private static void copy (InputStream in , OutputStream out ) throws IOException {
352+ byte [] buf = new byte [16 * 1024 ];
353+ for (int i ; (i = in .read (buf )) >= 0 ; ) {
354+ out .write (buf , 0 , i );
355+ }
356+ }
342357}
0 commit comments