1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 package ohos; 17 18 import java.io.BufferedInputStream; 19 import java.io.BufferedReader; 20 import java.io.ByteArrayOutputStream; 21 import java.io.File; 22 import java.io.FileInputStream; 23 import java.io.FileNotFoundException; 24 import java.io.FileOutputStream; 25 import java.io.IOException; 26 import java.io.InputStream; 27 import java.io.InputStreamReader; 28 29 import java.nio.charset.StandardCharsets; 30 31 import java.util.ArrayList; 32 import java.util.Enumeration; 33 import java.util.HashMap; 34 import java.util.List; 35 import java.util.Locale; 36 import java.util.stream.Collectors; 37 import java.util.zip.CRC32; 38 import java.util.zip.CheckedOutputStream; 39 import java.util.zip.ZipEntry; 40 import java.util.zip.ZipFile; 41 import java.util.zip.ZipInputStream; 42 import java.util.zip.ZipOutputStream; 43 44 /** 45 * bundle uncompress. 46 * 47 */ 48 public class Uncompress { 49 private static final String HAP_SUFFIX = ".hap"; 50 private static final String APK_SUFFIX = ".apk"; 51 private static final String JSON_SUFFIX = ".json"; 52 53 private static final String PACK_INFO = "pack.info"; 54 private static final String HARMONY_PROFILE = "config.json"; 55 private static final String MODULE_JSON = "module.json"; 56 private static final String RESOURCE_INDEX = "resources.index"; 57 private static final String RPCID_SC = "rpcid.sc"; 58 private static final String LINUX_FILE_SEPARATOR = "/"; 59 private static final String TEMP_PATH = "temp"; 60 private static final String HAP_SUFFIXI = ".hap"; 61 private static final String ENTRY_TYPE = "entry"; 62 private static final String SYSTEM_ACTION = "action.system.home"; 63 private static final String SYSTEM_WANT_HOME = "ohos.want.action.home"; 64 private static final String SYSTEM_ENTITY = "entity.system.home"; 65 private static final int READ_BUFFER_SIZE = 1024; 66 private static final int BUFFER_SIZE = 10 * 1024; 67 private static final String LIBS_DIR_NAME = "libs"; 68 private static final String CUT_ENTRY_FILENAME = "cut_entry.apk"; 69 private static final String SO_SUFFIX = ".so"; 70 private static final String RESOURCE_PATH = "resources/base/profile/"; 71 private static final String TRUE = "true"; 72 private static final String HQF_SUFFIX = ".hqf"; 73 private static final String PATCH_JSON = "patch.json"; 74 private static final String HAP_PREFIX = "HAP"; 75 private static final String HSP_SUFFIX = ".hsp"; 76 77 private static final Log LOG = new Log(Uncompress.class.toString()); 78 79 /** 80 * unpackage entrance. 81 * 82 * @param utility common data 83 * @return unpackageProcess if unpackage succeed 84 */ unpackageProcess(Utility utility)85 static boolean unpackageProcess(Utility utility) { 86 if (utility == null) { 87 LOG.error("Uncompress::unpackageProcess utility is null."); 88 return false; 89 } 90 boolean unpackageResult = true; 91 File destFile = new File(utility.getOutPath()); 92 93 if (!destFile.exists()) { 94 if (!destFile.mkdirs()) { 95 LOG.error("Uncompress::unpackageProcess create out file directory failed!"); 96 return false; 97 } 98 } 99 try { 100 if (!Utility.MODE_HAP.equals(utility.getMode()) || !TRUE.equals(utility.getRpcid())) { 101 if (!utility.getForceRewrite().isEmpty() && "true".equals(utility.getForceRewrite())) { 102 File outPath = new File(utility.getOutPath()); 103 deleteFile(outPath); 104 outPath.mkdirs(); 105 } 106 } 107 switch (utility.getMode()) { 108 case Utility.MODE_HAP: 109 unpackageHapMode(utility); 110 break; 111 case Utility.MODE_HAR: 112 dataTransferAllFiles(utility.getHarPath(), utility.getOutPath()); 113 break; 114 case Utility.MODE_APP: 115 dataTransferFilesByApp(utility, utility.getAppPath(), utility.getOutPath()); 116 break; 117 case Utility.MODE_APPQF: 118 uncompressAPPQFFile(utility); 119 break; 120 case Utility.MODE_HSP: 121 dataTransferAllFiles(utility.getHspPath(), utility.getOutPath()); 122 break; 123 default: 124 LOG.error("Uncompress::unpackageProcess input wrong type!"); 125 throw new BundleException("Uncompress::unpackageProcess input wrong type!"); 126 } 127 } catch (BundleException ignored) { 128 unpackageResult = false; 129 LOG.error("Uncompress::unpackageProcess Bundle exception"); 130 } 131 // return uncompress information. 132 if (!unpackageResult) { 133 LOG.error("Uncompress::unpackageProcess unpackage failed!"); 134 } 135 return unpackageResult; 136 } 137 138 /** 139 * unpack hap. 140 * 141 * @param utility common data 142 */ unpackageHapMode(Utility utility)143 static void unpackageHapMode(Utility utility) throws BundleException { 144 if (!Utility.MODE_HAP.equals(utility.getMode())) { 145 LOG.error("unpackageHapMode input wrong unpack mode: " + utility.getMode()); 146 throw new BundleException("Uncompress::unpackageHapMode input wrong unpack mode"); 147 } 148 try { 149 if (TRUE.equals(utility.getRpcid())) { 150 getRpcidFromHap(utility.getHapPath(), utility.getOutPath()); 151 return; 152 } 153 if (TRUE.equals(utility.getUnpackApk())) { 154 unzip(utility, utility.getHapPath(), utility.getOutPath(), APK_SUFFIX); 155 String[] temp = utility.getHapPath().replace("\\", "/").split("/"); 156 String hapName = temp[temp.length - 1]; 157 repackHap(utility.getHapPath(), utility.getOutPath(), hapName, utility.getUnpackApk()); 158 } else { 159 dataTransferAllFiles(utility.getHapPath(), utility.getOutPath()); 160 } 161 } catch (BundleException e) { 162 LOG.error("Uncompress::unpackageHapMode failed"); 163 throw new BundleException("Uncompress::unpackageHapMode failed"); 164 } 165 } 166 167 /** 168 * uncompress app. 169 * 170 * @param utility common data 171 * @return the uncompress result 172 */ uncompressAppByPath(Utility utility)173 static UncompressResult uncompressAppByPath(Utility utility) { 174 UncompressResult compressResult = new UncompressResult(); 175 InputStream input = null; 176 String srcPath = utility.getAppPath(); 177 String parseMode = utility.getParseMode(); 178 179 try { 180 if (UncompressEntrance.PARSE_MODE_HAPLIST.equals(parseMode)) { 181 compressResult = uncompress(utility.getDeviceType(), srcPath, PACK_INFO); 182 } else if (UncompressEntrance.PARSE_MODE_HAPINFO.equals(parseMode)) { 183 compressResult = uncompressHapAndHspFromAppPath(srcPath, utility); 184 } else if (UncompressEntrance.PARSE_MODE_ALL.equals(parseMode)) { 185 compressResult = uncompressAllAppByPath(srcPath); 186 } else { 187 LOG.error("Uncompress::uncompressApp parseMode is invalid!"); 188 compressResult.setResult(false); 189 compressResult.setMessage("ParseApp parseMode is invalid"); 190 } 191 } catch (BundleException e) { 192 LOG.error("Uncompress::uncompressApp Bundle exception"); 193 compressResult.setResult(false); 194 compressResult.setMessage("ParseApp Bundle exception"); 195 } finally { 196 Utility.closeStream(input); 197 } 198 return compressResult; 199 } 200 uncompressHapAndHspFromAppPath( String srcPath, Utility utility)201 private static UncompressResult uncompressHapAndHspFromAppPath( 202 String srcPath, Utility utility) throws BundleException { 203 UncompressResult result = new UncompressResult(); 204 String hapName = utility.getHapName(); 205 if (!hapName.toLowerCase(Locale.ENGLISH).endsWith(HAP_SUFFIX) 206 && !hapName.toLowerCase(Locale.ENGLISH).endsWith(HSP_SUFFIX)) { 207 hapName += HAP_SUFFIX; 208 } 209 ZipFile appFile = null; 210 ZipEntry entry = null; 211 InputStream stream = null; 212 try { 213 appFile = new ZipFile(srcPath); 214 Enumeration<? extends ZipEntry> entries = appFile.entries(); 215 while (entries.hasMoreElements()) { 216 entry = entries.nextElement(); 217 stream = appFile.getInputStream(entry); 218 if (!hapName.equals(entry.getName().toLowerCase(Locale.ENGLISH))) { 219 continue; 220 } 221 UncompressResult hapInfo = uncompressHapByStream("", stream, hapName); 222 if (hapInfo.getProfileInfos() != null && hapInfo.getProfileInfos().size() > 0) { 223 result.addProfileInfo(hapInfo.getProfileInfos().get(0)); 224 result.addProfileInfoStr(hapInfo.getProfileInfosStr().get(0)); 225 } 226 break; 227 } 228 } catch (IOException | BundleException e) { 229 LOG.error("uncompressHapFromAppPath failed: " + e.getMessage()); 230 throw new BundleException("uncompressHapFromAppPath failed!"); 231 } finally { 232 Utility.closeStream(appFile); 233 Utility.closeStream(stream); 234 } 235 return result; 236 } 237 uncompressAllAppByPath(String srcPath)238 private static UncompressResult uncompressAllAppByPath(String srcPath) throws BundleException { 239 UncompressResult result = new UncompressResult(); 240 ZipFile appFile = null; 241 ZipEntry entry = null; 242 InputStream stream = null; 243 try { 244 appFile = new ZipFile(srcPath); 245 Enumeration<? extends ZipEntry> entries = appFile.entries(); 246 while (entries.hasMoreElements()) { 247 entry = entries.nextElement(); 248 stream = appFile.getInputStream(entry); 249 if (PACK_INFO.equals(entry.getName().toLowerCase(Locale.ENGLISH))) { 250 String packInfo = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8)) 251 .lines().parallel().collect(Collectors.joining(System.lineSeparator())); 252 List<PackInfo> packInfos = JsonUtil.parseHapList("", packInfo); 253 result.setPackInfoStr(packInfo); 254 result.setPackInfos(packInfos); 255 } 256 if (entry.getName().toLowerCase(Locale.ENGLISH).endsWith(HAP_SUFFIX) 257 || entry.getName().toLowerCase(Locale.ENGLISH).endsWith(HSP_SUFFIX)) { 258 UncompressResult hapInfo = uncompressHapByStream("", stream, entry.getName()); 259 if (hapInfo.getProfileInfos() != null && hapInfo.getProfileInfos().size() > 0) { 260 result.addProfileInfo(hapInfo.getProfileInfos().get(0)); 261 result.addProfileInfoStr(hapInfo.getProfileInfosStr().get(0)); 262 } 263 } 264 } 265 result = checkParseAllResult(result); 266 result = obtainLabelAndIcon(result); 267 } catch (IOException | BundleException e) { 268 LOG.error("uncompressAllAppByPath failed: " + e.getMessage()); 269 throw new BundleException("uncompressAllAppByPath failed!"); 270 } finally { 271 Utility.closeStream(appFile); 272 Utility.closeStream(stream); 273 } 274 return result; 275 } 276 277 278 /** 279 * uncompress app. 280 * 281 * @param utility common data 282 * @param input the InputStream about the app package. 283 * @return the uncompress result 284 */ uncompressAppByInput(Utility utility, InputStream input)285 static UncompressResult uncompressAppByInput(Utility utility, InputStream input) { 286 UncompressResult compressResult = new UncompressResult(); 287 String parseMode = utility.getParseMode(); 288 try { 289 if (!parseMode.isEmpty() && UncompressEntrance.PARSE_MODE_HAPLIST.equals(parseMode)) { 290 compressResult = uncompressByInput(utility.getDeviceType(), input, PACK_INFO, ""); 291 } else if (!parseMode.isEmpty() && UncompressEntrance.PARSE_MODE_HAPINFO.equals(parseMode)) { 292 compressResult = uncompressHapFromAppStream(utility.getDeviceType(), input, utility.getHapName()); 293 } else if (!parseMode.isEmpty() && UncompressEntrance.PARSE_MODE_ALL.equals(parseMode)) { 294 compressResult = uncompressAllFromAppStream(input); 295 } else { 296 LOG.error("Uncompress::uncompressAppByInput parseMode is invalid!"); 297 compressResult.setResult(false); 298 compressResult.setMessage("ParseApp parseMode is invalid"); 299 } 300 } catch (BundleException exception) { 301 LOG.error("Uncompress::uncompressAppByInput Bundle exception"); 302 compressResult.setResult(false); 303 compressResult.setMessage("ParseApp Bundle exception"); 304 } 305 return compressResult; 306 } 307 uncompressHapFromAppStream(String deviceType, InputStream stream, String fileName)308 private static UncompressResult uncompressHapFromAppStream(String deviceType, InputStream stream, String fileName) 309 throws BundleException { 310 String hapFile = fileName; 311 if (!fileName.toLowerCase(Locale.ENGLISH).endsWith(HAP_SUFFIX) 312 && !fileName.toLowerCase(Locale.ENGLISH).endsWith(HSP_SUFFIX)) { 313 hapFile += HAP_SUFFIX; 314 } 315 UncompressResult result = new UncompressResult(); 316 ZipInputStream zipInputStream = null; 317 try { 318 zipInputStream = new ZipInputStream(stream); 319 ZipEntry appEntry; 320 while ((appEntry = zipInputStream.getNextEntry()) != null) { 321 if (appEntry.getName().toLowerCase(Locale.ENGLISH).equals(hapFile)) { 322 result = uncompressHapByStream("", zipInputStream, appEntry.getName()); 323 } 324 } 325 } catch (IOException e) { 326 LOG.error("uncompressHapFromAppStream failed: " + e.getMessage()); 327 throw new BundleException("uncompressHapFromAppStream failed!"); 328 } finally { 329 Utility.closeStream(zipInputStream); 330 } 331 return result; 332 } 333 uncompressAllFromAppStream(InputStream stream)334 private static UncompressResult uncompressAllFromAppStream(InputStream stream) throws BundleException { 335 UncompressResult result = new UncompressResult(); 336 ZipInputStream zipInputStream = null; 337 try { 338 zipInputStream = new ZipInputStream(stream); 339 ZipEntry entry; 340 while ((entry = zipInputStream.getNextEntry()) != null) { 341 if (PACK_INFO.equals(entry.getName().toLowerCase(Locale.ENGLISH))) { 342 String packInfo = new BufferedReader(new InputStreamReader(zipInputStream, 343 StandardCharsets.UTF_8)).lines().parallel() 344 .collect(Collectors.joining(System.lineSeparator())); 345 List<PackInfo> packInfos = JsonUtil.parseHapList("", packInfo); 346 result.setPackInfoStr(packInfo); 347 result.setPackInfos(packInfos); 348 } 349 if (entry.getName().toLowerCase(Locale.ENGLISH).endsWith(HAP_SUFFIX) 350 || entry.getName().toLowerCase(Locale.ENGLISH).endsWith(HSP_SUFFIX)) { 351 UncompressResult hapResult = uncompressHapByStream("", zipInputStream, entry.getName()); 352 if (hapResult.getProfileInfos() != null && hapResult.getProfileInfos().size() > 0) { 353 result.addProfileInfo(hapResult.getProfileInfos().get(0)); 354 result.addProfileInfoStr(hapResult.getProfileInfosStr().get(0)); 355 } 356 } 357 } 358 result = checkParseAllResult(result); 359 result = obtainLabelAndIcon(result); 360 } catch (IOException | BundleException e) { 361 LOG.error("uncompressAllFromAppStream failed: " + e.getMessage()); 362 throw new BundleException("uncompressAllFromAppStream failed!"); 363 } finally { 364 Utility.closeStream(zipInputStream); 365 } 366 return result; 367 } 368 369 /** 370 * uncompress hap. 371 * 372 * @param utility common data 373 * @return the uncompress result 374 */ uncompressHap(Utility utility)375 static UncompressResult uncompressHap(Utility utility) { 376 UncompressResult compressResult = new UncompressResult(); 377 try { 378 compressResult = uncompressHapByPath(utility.getDeviceType(), utility.getHapPath()); 379 } catch (BundleException ignored) { 380 LOG.error("Uncompress::uncompressHap Bundle exception"); 381 compressResult.setResult(false); 382 compressResult.setMessage("uncompressHap Bundle exception"); 383 } 384 return compressResult; 385 } 386 387 /** 388 * uncompress hap by path, it can adapt stage module and fa module. 389 * 390 * @param deviceType indicates the device type of parse type. 391 * @param hapPath indicates the hap path of hap. 392 * @return the uncompress result 393 */ uncompressHapByPath(String deviceType, String hapPath)394 static UncompressResult uncompressHapByPath(String deviceType, String hapPath) throws BundleException { 395 UncompressResult compressResult = new UncompressResult(); 396 try { 397 if (isModuleHap(hapPath, compressResult)) { 398 compressResult = unCompressModuleHap(deviceType, hapPath, MODULE_JSON); 399 } else { 400 compressResult = uncompress(deviceType, hapPath, HARMONY_PROFILE); 401 compressResult = obtainLabelAndIcon(compressResult); 402 } 403 } catch (BundleException e) { 404 LOG.error("Uncompress::uncompressHapByPath Bundle exception"); 405 throw new BundleException("Uncompress::uncompressHapByPath failed"); 406 } 407 return compressResult; 408 } 409 410 /** 411 * uncompress hap. 412 * 413 * @param utility common data 414 * @param input the InputStream about the app package. 415 * @return the uncompress result 416 */ uncompressHapByInput(Utility utility, InputStream input)417 static UncompressResult uncompressHapByInput(Utility utility, InputStream input) { 418 UncompressResult compressResult = new UncompressResult(); 419 try { 420 compressResult = uncompressHapByStream(utility.getDeviceType(), input, ""); 421 } catch (BundleException ignored) { 422 LOG.error("Uncompress::uncompressHapByInput Bundle exception"); 423 compressResult.setResult(false); 424 compressResult.setMessage("uncompressHapByInput Bundle exception"); 425 } 426 return compressResult; 427 } 428 429 /** 430 * uncompress hap by InputStream, it can adapt stage module and fa module. 431 * 432 * @param deviceType indicates the device type of parse type. 433 * @param stream indicates the input stream of hap. 434 * @return the uncompress result 435 */ uncompressHapByStream(String deviceType, InputStream stream, String hapName)436 static UncompressResult uncompressHapByStream(String deviceType, InputStream stream, 437 String hapName) throws BundleException { 438 UncompressResult compressResult = new UncompressResult(); 439 compressResult = uncompressHapByBigStream(deviceType, stream, hapName); 440 return compressResult; 441 } 442 uncompressHapByBigStream(String deviceType, InputStream stream, String hapName)443 static UncompressResult uncompressHapByBigStream(String deviceType, InputStream stream, String hapName) 444 throws BundleException { 445 UncompressResult compressResult = new UncompressResult(); 446 InputStream fileStream = null; 447 InputStream parseStream = null; 448 File file = null; 449 try { 450 String releativePath = System.getProperty("user.dir"); 451 File directory = new File(releativePath); 452 file = File.createTempFile(HAP_PREFIX, HAP_SUFFIX, directory); 453 writeToTempFile(stream, file); 454 fileStream = new FileInputStream(file); 455 boolean isModule = false; 456 if (isModuleInput(fileStream)) { 457 isModule = true; 458 } 459 parseStream = new FileInputStream(file); 460 if (isModule) { 461 compressResult = uncompressModuleHapByInput(deviceType, parseStream, MODULE_JSON, hapName); 462 } else { 463 compressResult = uncompressByInput(deviceType, parseStream, HARMONY_PROFILE, hapName); 464 compressResult = obtainLabelAndIcon(compressResult); 465 } 466 } catch (IOException e) { 467 LOG.error("uncompressHapByBigStream failed for IO exception: " + e.getMessage()); 468 throw new BundleException("uncompressHapByBigStream failed for IO exception!"); 469 } finally { 470 Utility.closeStream(fileStream); 471 Utility.closeStream(parseStream); 472 if (file != null) { 473 FileUtils.deleteFile(file.getPath()); 474 } 475 } 476 return compressResult; 477 } 478 479 /** 480 * unzip process 481 * 482 * @param utility common data 483 * @param srcPath source file path 484 * @param destDirPath destination file path 485 * @param suffix suffix for judgment 486 * @throws BundleException FileNotFoundException|IOException. 487 */ unzip(Utility utility, String srcPath, String destDirPath, String suffix)488 private static void unzip(Utility utility, String srcPath, String destDirPath, String suffix) 489 throws BundleException { 490 if (utility == null) { 491 LOG.error("Uncompress::unzip utility is null!"); 492 throw new BundleException("Unzip failed, utility is null"); 493 } 494 495 if (srcPath.isEmpty() || !UncompressVerify.isPathValid(srcPath, true, "")) { 496 LOG.error("Uncompress::unzip srcPath is invalid!"); 497 throw new BundleException("Unzip failed, srcPath is invalid"); 498 } 499 500 if (destDirPath.isEmpty() || !UncompressVerify.isPathValid(destDirPath, false, null)) { 501 LOG.error("Uncompress::unzip destDirPath is invalid!"); 502 throw new BundleException("Unzip failed, destDirPath is invalid"); 503 } 504 unzipFromFile(utility, srcPath, destDirPath, suffix); 505 } 506 507 /** 508 * unzip process from the file 509 * 510 * @param utility common data 511 * @param srcPath source file path 512 * @param destDirPath destination file path 513 * @param suffix suffix for judgment 514 * @throws BundleException FileNotFoundException|IOException. 515 */ unzipFromFile(Utility utility, String srcPath, String destDirPath, String suffix)516 private static void unzipFromFile(Utility utility, String srcPath, String destDirPath, String suffix) 517 throws BundleException { 518 ZipFile zipFile = null; 519 String hapNames = ""; 520 try { 521 zipFile = new ZipFile(new File(srcPath)); 522 if (utility != null && !utility.getDeviceType().isEmpty() 523 && (HAP_SUFFIX.equals(suffix) || HSP_SUFFIX.equals(suffix))) { 524 List<PackInfo> packInfos = uncompress(utility.getDeviceType(), srcPath, PACK_INFO).getPackInfos(); 525 for (PackInfo packinfo : packInfos) { 526 hapNames += packinfo.name + ","; 527 } 528 } 529 530 int entriesNum = 0; 531 for (Enumeration<? extends ZipEntry> entries = zipFile.entries(); entries.hasMoreElements(); ) { 532 entriesNum++; 533 ZipEntry entry = entries.nextElement(); 534 String entryName = ""; 535 if (entry == null || entry.getName().isEmpty()) { 536 continue; 537 } 538 if (entry.getName().toLowerCase().endsWith(CUT_ENTRY_FILENAME) && 539 "false".equals(utility.getUnpackCutEntryApk())) { 540 continue; 541 } 542 entryName = entry.getName(); 543 if (!entryName.toLowerCase(Locale.ENGLISH).endsWith(suffix) || 544 (!hapNames.isEmpty() && !hapNames.contains(entryName.replace(suffix, "")))) { 545 continue; 546 } 547 String tempDir = destDirPath.replace(File.separator, LINUX_FILE_SEPARATOR); 548 if (HAP_SUFFIX.equals(suffix) && "true".equals(utility.getUnpackApk())) { 549 tempDir = tempDir + LINUX_FILE_SEPARATOR + entryName.replace(suffix, ""); 550 File destFileDir = new File(tempDir); 551 if (!destFileDir.exists()) { 552 destFileDir.mkdir(); 553 } 554 } 555 if (APK_SUFFIX.equals(suffix) && "true".equals(utility.getUnpackApk()) 556 && entryName.contains(LINUX_FILE_SEPARATOR)) { 557 // only unpack shell apk which in the root directory 558 continue; 559 } 560 String tempPath = tempDir + LINUX_FILE_SEPARATOR + entryName; 561 if (!FileUtils.matchPattern(tempPath)) { 562 LOG.error("Input invalid file: " + tempPath); 563 throw new BundleException("Input invalid file " + tempPath); 564 } 565 File destFile = new File(tempPath); 566 dataTransfer(zipFile, entry, destFile); 567 if (JSON_SUFFIX.equals(suffix)) { 568 break; 569 } else if (HAP_SUFFIX.equals(suffix) && "true".equals(utility.getUnpackApk())) { 570 unzip(utility, tempPath, tempDir, APK_SUFFIX); 571 repackHap(tempPath, tempDir, entryName, utility.getUnpackApk()); 572 } 573 } 574 } catch (IOException | BundleException exception) { 575 LOG.error("Uncompress::unzipInHapMode failed: " + exception.getMessage()); 576 throw new BundleException("Unzip in hap mode failed"); 577 } finally { 578 Utility.closeStream(zipFile); 579 } 580 } 581 582 /** 583 * uncompress dataTransfer 584 * 585 * @param zipFile input zip file 586 * @param entry input file in zip 587 * @param destFile output file path 588 * @throws BundleException FileNotFoundException|IOException. 589 */ dataTransfer(ZipFile zipFile, ZipEntry entry, File destFile)590 private static void dataTransfer(ZipFile zipFile, ZipEntry entry, File destFile) throws BundleException { 591 InputStream fileInputStream = null; 592 FileOutputStream fileOutStream = null; 593 try { 594 if (!FileUtils.matchPattern(destFile.getCanonicalPath())) { 595 LOG.error("Input invalid file " + destFile.getCanonicalPath()); 596 throw new BundleException("Input invalid file" + destFile.getCanonicalPath()); 597 } 598 fileInputStream = zipFile.getInputStream(entry); 599 fileOutStream = new FileOutputStream(destFile); 600 byte[] data = new byte[BUFFER_SIZE]; 601 int count = fileInputStream.read(data); 602 int total = 0; 603 while (count > 0) { 604 fileOutStream.write(data, 0, count); 605 total += count; 606 count = fileInputStream.read(data); 607 } 608 } catch (IOException | BundleException exception) { 609 LOG.error("Uncompress::dataTransfer file " + exception.getMessage()); 610 throw new BundleException("DataTransfer failed"); 611 } finally { 612 Utility.closeStream(fileOutStream); 613 Utility.closeStream(fileInputStream); 614 } 615 } 616 617 /** 618 * uncompress dataTransfer all files. 619 * 620 * @param srcPath source file path 621 * @param destDirPath destination file path 622 * @throws BundleException FileNotFoundException|IOException. 623 */ dataTransferAllFiles(String srcPath, String destDirPath)624 private static void dataTransferAllFiles(String srcPath, String destDirPath) throws BundleException { 625 ZipFile zipFile = null; 626 try { 627 if (!FileUtils.matchPattern(srcPath)) { 628 throw new BundleException("Input invalid file " + srcPath); 629 } 630 zipFile = new ZipFile(new File(srcPath)); 631 int entriesNum = 0; 632 for (Enumeration<? extends ZipEntry> entries = zipFile.entries(); entries.hasMoreElements(); ) { 633 entriesNum++; 634 ZipEntry entry = entries.nextElement(); 635 if (entry == null) { 636 continue; 637 } 638 String tempPath = destDirPath + LINUX_FILE_SEPARATOR + entry.getName(); 639 File destFile = new File(tempPath); 640 if (destFile != null && destFile.getParentFile() != null && !destFile.getParentFile().exists()) { 641 destFile.getParentFile().mkdirs(); 642 } 643 dataTransfer(zipFile, entry, destFile); 644 } 645 } catch (FileNotFoundException ignored) { 646 LOG.error("Uncompress::unzipApk file not found exception: " + ignored.getMessage()); 647 throw new BundleException("Unzip Apk failed"); 648 } catch (IOException exception) { 649 LOG.error("Uncompress::unzipApk io exception: " + exception.getMessage()); 650 throw new BundleException("Unzip Apk failed"); 651 } finally { 652 Utility.closeStream(zipFile); 653 } 654 } 655 dataTransferFilesByApp(Utility utility, String srcPath, String destDirPath)656 private static void dataTransferFilesByApp(Utility utility, String srcPath, String destDirPath) 657 throws BundleException { 658 ZipFile zipFile = null; 659 try { 660 zipFile = new ZipFile(new File(srcPath)); 661 int entriesNum = 0; 662 for (Enumeration<? extends ZipEntry> entries = zipFile.entries(); entries.hasMoreElements(); ) { 663 entriesNum++; 664 ZipEntry entry = entries.nextElement(); 665 if (entry == null) { 666 continue; 667 } 668 String filePath = destDirPath + LINUX_FILE_SEPARATOR + entry.getName(); 669 if (!FileUtils.matchPattern(filePath)) { 670 throw new BundleException("Input invalid path " + filePath); 671 } 672 File destFile = new File(filePath); 673 if (destFile != null && destFile.getParentFile() != null && !destFile.getParentFile().exists()) { 674 destFile.getParentFile().mkdirs(); 675 } 676 boolean isUnpackApk = "true".equals(utility.getUnpackApk()); 677 if (isUnpackApk && filePath.toLowerCase().endsWith(HAP_SUFFIX)) { 678 dataTransfer(zipFile, entry, destFile); 679 unzip(utility, filePath, destDirPath, APK_SUFFIX); 680 String[] temp = filePath.replace("\\", "/").split("/"); 681 String hapName = ""; 682 if (temp.length > 0) { 683 hapName = temp[temp.length - 1]; 684 } 685 repackHap(filePath, destDirPath, hapName, utility.getUnpackApk()); 686 } else { 687 dataTransfer(zipFile, entry, destFile); 688 } 689 } 690 } catch (IOException | BundleException exception) { 691 LOG.error("Uncompress::unzipApk file failed " + exception.getMessage()); 692 throw new BundleException("Unzip Apk failed"); 693 } finally { 694 Utility.closeStream(zipFile); 695 } 696 } 697 getResourceDataFromHap(ZipFile zipFile)698 private static byte[] getResourceDataFromHap(ZipFile zipFile) throws BundleException, IOException { 699 int entriesNum = 0; 700 InputStream indexInputStream = null; 701 try { 702 for (Enumeration<? extends ZipEntry> entries = zipFile.entries(); entries.hasMoreElements(); ) { 703 entriesNum++; 704 ZipEntry indexEntry = entries.nextElement(); 705 if (indexEntry == null) { 706 continue; 707 } 708 if (indexEntry != null && !"".equals(indexEntry.getName()) && 709 indexEntry.getName().toLowerCase().endsWith(RESOURCE_INDEX)) { 710 indexInputStream = zipFile.getInputStream(indexEntry); 711 return getByte(indexInputStream); 712 } 713 } 714 } finally { 715 Utility.closeStream(indexInputStream); 716 } 717 return null; 718 } 719 unZipHapFileFromHapFile(String srcPath)720 private static HapZipInfo unZipHapFileFromHapFile(String srcPath) 721 throws BundleException, IOException { 722 HapZipInfo hapZipInfo = new HapZipInfo(); 723 ZipFile zipFile = null; 724 if (!FileUtils.matchPattern(srcPath)) { 725 LOG.error("Input invalid path " + srcPath); 726 throw new BundleException("Input invalid path " + srcPath); 727 } 728 try { 729 File srcFile = new File(srcPath); 730 zipFile = new ZipFile(srcFile); 731 hapZipInfo.setHarmonyProfileJsonStr(FileUtils.getFileStringFromZip(HARMONY_PROFILE, zipFile)); 732 hapZipInfo.setResDataBytes(getResourceDataFromHap(zipFile)); 733 hapZipInfo.setPackInfoJsonStr(FileUtils.getFileStringFromZip(PACK_INFO, zipFile)); 734 hapZipInfo.setHapFileName(getHapNameWithoutSuffix(srcFile.getName())); 735 } finally { 736 Utility.closeStream(zipFile); 737 } 738 return hapZipInfo; 739 } 740 741 /** 742 * uncompress from specified file name 743 * 744 * @param deviceType device type 745 * @param srcPath source file path 746 * @param fileName uncompress file name 747 * @return the uncompress result 748 * @throws BundleException FileNotFoundException|IOException. 749 */ uncompress(String deviceType, String srcPath, String fileName)750 private static UncompressResult uncompress(String deviceType, String srcPath, String fileName) 751 throws BundleException { 752 if (srcPath.isEmpty() || fileName.isEmpty()) { 753 LOG.error("Uncompress::uncompress srcPath, fileName is empty!"); 754 throw new BundleException("Uncompress failed, srcPath or fileName is empty"); 755 } 756 757 UncompressResult result = new UncompressResult(); 758 try { 759 HapZipInfo hapZipInfo = unZipHapFileFromHapFile(srcPath); 760 if (isPackInfo(fileName)) { 761 uncompressPackInfo(deviceType, hapZipInfo, result); 762 } else { 763 uncompressProfileInfo(hapZipInfo, result); 764 } 765 } catch (IOException exception) { 766 LOG.error("Uncompress::uncompress io exception: " + exception.getMessage()); 767 throw new BundleException("Uncompress failed"); 768 } 769 return result; 770 } 771 uncompressPackInfo(String deviceType, HapZipInfo hapZipInfo, UncompressResult uncomperssResult)772 private static void uncompressPackInfo(String deviceType, HapZipInfo hapZipInfo, UncompressResult uncomperssResult) 773 throws BundleException { 774 List<PackInfo> packInfos = JsonUtil.parseHapList(deviceType, hapZipInfo.getPackInfoJsonStr()); 775 uncomperssResult.setPackInfoStr(hapZipInfo.getPackInfoJsonStr()); 776 uncomperssResult.setPackInfos(packInfos); 777 } 778 uncompressProfileInfo(HapZipInfo hapZipInfo, UncompressResult uncomperssResult)779 private static void uncompressProfileInfo(HapZipInfo hapZipInfo, UncompressResult uncomperssResult) 780 throws BundleException { 781 ProfileInfo profileInfo = JsonUtil.parseProfileInfo(hapZipInfo.getHarmonyProfileJsonStr(), 782 hapZipInfo.getResDataBytes(), hapZipInfo.getPackInfoJsonStr(), hapZipInfo.getHapFileName()); 783 profileInfo.hapName = hapZipInfo.getHapFileName(); 784 profileInfo.appInfo.setBundleType(getFABundleType(profileInfo)); 785 uncomperssResult.addProfileInfoStr(hapZipInfo.getHarmonyProfileJsonStr()); 786 uncomperssResult.addProfileInfo(profileInfo); 787 } 788 getFABundleType(ProfileInfo profileInfo)789 private static String getFABundleType(ProfileInfo profileInfo) { 790 String bundleType = "app"; 791 if (profileInfo.hapInfo.distro.installationFree == 1) { 792 bundleType = "atomicService"; 793 } 794 return bundleType; 795 } 796 unZipHapFileFromInputStream(InputStream input)797 private static HapZipInfo unZipHapFileFromInputStream(InputStream input) throws BundleException, IOException { 798 BufferedInputStream bufIn = null; 799 ZipInputStream zipIn = null; 800 BufferedReader bufferedReader = null; 801 HapZipInfo hapZipInfo = new HapZipInfo(); 802 try { 803 ZipEntry entry = null; 804 bufIn = new BufferedInputStream(input); 805 zipIn = new ZipInputStream(bufIn); 806 int entriesNum = 0; 807 while ((entry = zipIn.getNextEntry()) != null) { 808 entriesNum++; 809 if (entry.getName().toLowerCase().endsWith(RESOURCE_INDEX)) { 810 hapZipInfo.setResDataBytes(getByte(zipIn)); 811 continue; 812 } 813 if (isPackInfo(entry.getName())) { 814 bufferedReader = new BufferedReader(new InputStreamReader(zipIn)); 815 hapZipInfo.setPackInfoJsonStr(readStringFromInputStream(zipIn, bufferedReader)); 816 continue; 817 } 818 if (isHarmonyProfile(entry.getName())) { 819 bufferedReader = new BufferedReader(new InputStreamReader(zipIn)); 820 hapZipInfo.setHarmonyProfileJsonStr(readStringFromInputStream(zipIn, bufferedReader)); 821 } 822 } 823 } finally { 824 Utility.closeStream(bufferedReader); 825 Utility.closeStream(bufIn); 826 Utility.closeStream(zipIn); 827 } 828 return hapZipInfo; 829 } 830 readStringFromInputStream(ZipInputStream zipIn, BufferedReader bufferedReader)831 private static String readStringFromInputStream(ZipInputStream zipIn, BufferedReader bufferedReader) 832 throws IOException { 833 String line; 834 StringBuilder sb = new StringBuilder(); 835 while ((line = bufferedReader.readLine()) != null) { 836 sb.append(line); 837 } 838 return sb.toString(); 839 } 840 841 /** 842 * uncompress process by InputStream 843 * 844 * @param deviceType device type 845 * @param input the InputStream about the package. 846 * @param fileName uncompress file name 847 * @return the uncompress result 848 * @throws BundleException FileNotFoundException|IOException. 849 */ uncompressByInput(String deviceType, InputStream input, String fileName, String hapName)850 private static UncompressResult uncompressByInput(String deviceType, InputStream input, 851 String fileName, String hapName) throws BundleException { 852 UncompressResult result = new UncompressResult(); 853 try { 854 HapZipInfo hapZipInfo = unZipHapFileFromInputStream(input); 855 hapZipInfo.setHapFileName(hapName); 856 if (isPackInfo(fileName)) { 857 uncompressPackInfo(deviceType, hapZipInfo, result); 858 } else { 859 uncompressProfileInfo(hapZipInfo, result); 860 } 861 } catch (IOException exception) { 862 LOG.error("Uncompress::uncompressByInput io exception: " + exception.getMessage()); 863 throw new BundleException("Uncompress by input failed"); 864 } 865 return result; 866 } 867 868 /** 869 * uncompress process by InputStream 870 * 871 * @param deviceType device type 872 * @param input the InputStream about the package. 873 * @param fileName uncompress file name 874 * @return the module uncompress result 875 * @throws BundleException FileNotFoundException|IOException. 876 */ uncompressModuleByInput(String deviceType, InputStream input, String fileName, String hapName)877 private static ModuleResult uncompressModuleByInput(String deviceType, InputStream input, 878 String fileName, String hapName) throws BundleException { 879 ModuleResult result = new ModuleResult(); 880 try { 881 HapZipInfo hapZipInfo = unZipModuleHapFileFromInputStream(input); 882 hapZipInfo.setHapFileName(hapName); 883 if (isPackInfo(fileName)) { 884 // for parse app 885 } else { 886 uncompressModuleJsonInfo(hapZipInfo, result); 887 } 888 } catch (BundleException exception) { 889 LOG.error("Uncompress::uncompressByInput io exception: " + exception.getMessage()); 890 throw new BundleException("Uncompress by input failed"); 891 } 892 return result; 893 } 894 895 /** 896 * Get entry byte array. 897 * 898 * @param zis the InputStream about the entry. 899 * @return Return the entry byte array. 900 * @throws BundleException FileNotFoundException|IOException. 901 */ getByte(InputStream zis)902 private static byte[] getByte(InputStream zis) throws BundleException { 903 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 904 byte[] buf = null; 905 try { 906 byte[] temp = new byte[READ_BUFFER_SIZE]; 907 int length = 0; 908 909 while ((length = zis.read(temp, 0, READ_BUFFER_SIZE)) != -1) { 910 bos.write(temp, 0, length); 911 } 912 913 buf = bos.toByteArray(); 914 } catch (IOException e) { 915 LOG.error("Uncompress::getByte io exception: " + e.getMessage()); 916 throw new BundleException("Get byte failed"); 917 } finally { 918 Utility.closeStream(bos); 919 } 920 return buf; 921 } 922 923 /** 924 * repack hap 925 * 926 * @param srcPath source file path 927 * @param destDirPath destination file path 928 * @param fileName target file name 929 * @param unpackApk unpackApk flag 930 * @throws BundleException FileNotFoundException|IOException. 931 */ repackHap(String srcPath, String destDirPath, String fileName, String unpackApk)932 private static void repackHap(String srcPath, String destDirPath, String fileName, String unpackApk) 933 throws BundleException { 934 if (srcPath.isEmpty() || destDirPath.isEmpty() || fileName.isEmpty()) { 935 LOG.error("Uncompress::repackHap srcPath, destDirPath or fileName is empty!"); 936 throw new BundleException("Repack hap failed, srcPath, destDirPath or fileName is empty"); 937 } 938 939 if (!UncompressVerify.isPathValid(srcPath, true, "")) { 940 LOG.error("Uncompress::repackHap srcPath is invalid!"); 941 throw new BundleException("Repack hap failed, srcPath is invalid"); 942 } 943 944 if (!UncompressVerify.isPathValid(destDirPath, false, null)) { 945 LOG.error("Uncompress::repackHap destDirPath is invalid!"); 946 throw new BundleException("Repack hap failed, destDirPath is invalid"); 947 } 948 949 String tempDir = destDirPath.replace(File.separator, LINUX_FILE_SEPARATOR) + LINUX_FILE_SEPARATOR + 950 TEMP_PATH; 951 dataTransferAllFiles(srcPath, tempDir); 952 packFilesByPath(tempDir, destDirPath, fileName, unpackApk); 953 File deleteFile = new File(tempDir); 954 deleteFile(deleteFile); 955 } 956 957 /** 958 * compress file directory. 959 * 960 * @param srcPath source file path 961 * @param destDirPath destination file path 962 * @param fileName target file name 963 * @param unpackApk unpackApk flag 964 * @throws BundleException FileNotFoundException|IOException. 965 */ packFilesByPath(String srcPath, String destDirPath, String fileName, String unpackApk)966 private static void packFilesByPath(String srcPath, String destDirPath, String fileName, String unpackApk) 967 throws BundleException { 968 if (srcPath.isEmpty() || destDirPath.isEmpty() || fileName.isEmpty()) { 969 LOG.error("Uncompress::packFilesByPath srcPath, destDirPath or fileName is empty!"); 970 throw new BundleException("Pack files by path failed, srcPath, destDirPath or fileName is empty"); 971 } 972 973 if (!UncompressVerify.isPathValid(srcPath, false, null) || 974 !UncompressVerify.isPathValid(destDirPath, false, null)) { 975 LOG.error("Uncompress::packFilesByPath srcPath or destDirPath is invalid!"); 976 throw new BundleException("Pack files by path failed, srcPath or destDirPath is invalid"); 977 } 978 979 File srcDir = new File(srcPath); 980 File[] srcFiles = srcDir.listFiles(); 981 if (srcFiles == null) { 982 return; 983 } 984 FileOutputStream fileOut = null; 985 CheckedOutputStream checkedOut = null; 986 ZipOutputStream zipOut = null; 987 988 try { 989 String zipPath = destDirPath + LINUX_FILE_SEPARATOR + fileName; 990 if (!FileUtils.matchPattern(zipPath)) { 991 throw new BundleException("Input invalid file" + zipPath); 992 } 993 File zipFile = new File(zipPath); 994 fileOut = new FileOutputStream(zipFile); 995 checkedOut = new CheckedOutputStream(fileOut, new CRC32()); 996 zipOut = new ZipOutputStream(checkedOut); 997 for (int i = 0; i < srcFiles.length; i++) { 998 File srcFile = srcFiles[i]; 999 if (srcFile.isDirectory()) { 1000 if (srcFile.getPath().toLowerCase(Locale.ENGLISH).endsWith(LIBS_DIR_NAME)) { 1001 compressDirectory(srcFile, "", zipOut, true); 1002 } else { 1003 compressDirectory(srcFile, "", zipOut, false); 1004 } 1005 } else { 1006 if (srcFile.getPath().toLowerCase(Locale.ENGLISH).endsWith(APK_SUFFIX) && 1007 "true".equals(unpackApk)) { 1008 continue; 1009 } 1010 compressFile(srcFile, "", zipOut, false); 1011 } 1012 } 1013 } catch (FileNotFoundException | BundleException exception) { 1014 LOG.error("Uncompress::packFilesByPath " + exception.getMessage()); 1015 throw new BundleException("Pack files by path failed"); 1016 } finally { 1017 Utility.closeStream(zipOut); 1018 Utility.closeStream(checkedOut); 1019 Utility.closeStream(fileOut); 1020 } 1021 } 1022 1023 /** 1024 * compress file directory. 1025 * 1026 * @param dir file directory 1027 * @param baseDir base path for file 1028 * @param zipOut zip outPutStream 1029 * @param isCompression if need compression 1030 * @throws BundleException FileNotFoundException|IOException. 1031 */ compressDirectory(File dir, String baseDir, ZipOutputStream zipOut, boolean isCompression)1032 private static void compressDirectory(File dir, String baseDir, ZipOutputStream zipOut, boolean isCompression) 1033 throws BundleException { 1034 File[] files = dir.listFiles(); 1035 if (files == null) { 1036 return; 1037 } 1038 for (File file : files) { 1039 if (file.isDirectory()) { 1040 compressDirectory(file, baseDir + dir.getName() + File.separator, zipOut, isCompression); 1041 } else { 1042 compressFile(file, baseDir + dir.getName() + File.separator, zipOut, isCompression); 1043 } 1044 } 1045 } 1046 1047 /** 1048 * compress process. 1049 * 1050 * @param srcFile source file to zip 1051 * @param baseDir base path for file 1052 * @param zipOut zip outPutStream 1053 * @param isCompression if need compression 1054 * @throws BundleException FileNotFoundException|IOException. 1055 */ compressFile(File srcFile, String baseDir, ZipOutputStream zipOut, boolean isCompression)1056 private static void compressFile(File srcFile, String baseDir, ZipOutputStream zipOut, boolean isCompression) 1057 throws BundleException { 1058 FileInputStream fileInputStream = null; 1059 BufferedInputStream bufferedInputStream = null; 1060 1061 try { 1062 String entryName = (baseDir + srcFile.getName()).replace(File.separator, LINUX_FILE_SEPARATOR); 1063 ZipEntry zipEntry = new ZipEntry(entryName); 1064 boolean isNeedCompress = isCompression; 1065 if (srcFile.isFile() && srcFile.getName().toLowerCase(Locale.ENGLISH).endsWith(SO_SUFFIX)) { 1066 isNeedCompress = false; 1067 } 1068 if (isNeedCompress) { 1069 zipEntry.setMethod(ZipEntry.DEFLATED); 1070 } else { 1071 zipEntry.setMethod(ZipEntry.STORED); 1072 zipEntry.setCompressedSize(srcFile.length()); 1073 zipEntry.setSize(srcFile.length()); 1074 CRC32 crc = getCrcFromFile(srcFile); 1075 zipEntry.setCrc(crc.getValue()); 1076 } 1077 zipOut.putNextEntry(zipEntry); 1078 byte[] data = new byte[BUFFER_SIZE]; 1079 fileInputStream = new FileInputStream(srcFile); 1080 bufferedInputStream = new BufferedInputStream(fileInputStream); 1081 int count = bufferedInputStream.read(data); 1082 while (count > 0) { 1083 zipOut.write(data, 0, count); 1084 count = bufferedInputStream.read(data); 1085 } 1086 } catch (FileNotFoundException ignored) { 1087 LOG.error("Uncompress::compressFile file not found exception: " + ignored.getMessage()); 1088 throw new BundleException("Compress file failed"); 1089 } catch (IOException exception) { 1090 LOG.error("Uncompress::compressFile io exception: " + exception.getMessage()); 1091 throw new BundleException("Compress file failed"); 1092 } finally { 1093 Utility.closeStream(fileInputStream); 1094 Utility.closeStream(bufferedInputStream); 1095 } 1096 } 1097 1098 /** 1099 * get CRC32 from file. 1100 * 1101 * @param file source file 1102 * @return CRC32 1103 * @throws BundleException FileNotFoundException|IOException. 1104 */ getCrcFromFile(File file)1105 private static CRC32 getCrcFromFile(File file) throws BundleException { 1106 FileInputStream fileInputStream = null; 1107 CRC32 crc = new CRC32(); 1108 try { 1109 fileInputStream = new FileInputStream(file); 1110 byte[] buffer = new byte[BUFFER_SIZE]; 1111 1112 int count = fileInputStream.read(buffer); 1113 while (count > 0) { 1114 crc.update(buffer, 0, count); 1115 count = fileInputStream.read(buffer); 1116 } 1117 } catch (FileNotFoundException ignored) { 1118 LOG.error("Uncompressor::getCrcFromFile file not found exception"); 1119 throw new BundleException("Get Crc from file failed"); 1120 } catch (IOException exception) { 1121 LOG.error("Uncompressor::getCrcFromFile io exception: " + exception.getMessage()); 1122 throw new BundleException("Get Crc from file failed"); 1123 } finally { 1124 Utility.closeStream(fileInputStream); 1125 } 1126 return crc; 1127 } 1128 1129 /** 1130 * delete file 1131 * 1132 * @param file the file to be deleted 1133 */ deleteFile(File file)1134 private static void deleteFile(File file) { 1135 if (file.exists()) { 1136 if (file.isDirectory()) { 1137 File[] files = file.listFiles(); 1138 for (int i = 0; i < files.length; i++) { 1139 deleteFile(files[i]); 1140 } 1141 } 1142 file.delete(); 1143 } 1144 } 1145 1146 /** 1147 * check 1148 * 1149 * @param result the result of parse app all mode 1150 * @return return the result of checkParseAllResult. 1151 */ checkParseAllResult(UncompressResult result)1152 private static UncompressResult checkParseAllResult(UncompressResult result) { 1153 UncompressResult errorResult = new UncompressResult(); 1154 errorResult.setResult(false); 1155 errorResult.setMessage("App package is invalid."); 1156 if (result == null || result.getPackInfos() == null || result.getProfileInfos() == null) { 1157 return errorResult; 1158 } 1159 1160 List<PackInfo> packInfos = result.getPackInfos(); 1161 List<ProfileInfo> profileInfos = result.getProfileInfos(); 1162 int packInfoSize = packInfos.size(); 1163 int profileInfoSize = profileInfos.size(); 1164 if (packInfoSize == 0 || profileInfoSize == 0 || packInfoSize != profileInfoSize) { 1165 LOG.error("Uncompress::checkParseAllResult error, hapNum is invalid in app"); 1166 return errorResult; 1167 } 1168 1169 for (int i = 0; i < packInfoSize; i++) { 1170 if (packInfos.get(i) == null || packInfos.get(i).name.isEmpty()) { 1171 return errorResult; 1172 } 1173 boolean isHave = false; 1174 for (int j = 0; j < profileInfoSize; j++) { 1175 if (profileInfos.get(j) == null || profileInfos.get(j).hapName.isEmpty()) { 1176 return errorResult; 1177 } 1178 if (comparePackAndProfile(packInfos.get(i), profileInfos.get(j))) { 1179 isHave = true; 1180 break; 1181 } 1182 } 1183 if (!isHave) { 1184 return errorResult; 1185 } 1186 } 1187 1188 return result; 1189 } 1190 1191 /** 1192 * get label and icon for application 1193 * 1194 * @param result the result of parse app all mode 1195 * @return return the result which contains icon and label 1196 */ obtainLabelAndIcon(UncompressResult result)1197 private static UncompressResult obtainLabelAndIcon(UncompressResult result) { 1198 List<ProfileInfo> profileInfos = result.getProfileInfos(); 1199 if (profileInfos.isEmpty()) { 1200 return result; 1201 } 1202 for (ProfileInfo profileInfo : profileInfos) { 1203 if (profileInfo == null) { 1204 continue; 1205 } 1206 HapInfo hapInfo = profileInfo.hapInfo; 1207 if (hapInfo == null) { 1208 continue; 1209 } 1210 Distro distro = hapInfo.distro; 1211 if (distro == null) { 1212 continue; 1213 } 1214 String moduleType = distro.moduleType; 1215 if (ENTRY_TYPE.equals(moduleType.toLowerCase(Locale.ENGLISH))) { 1216 return obtainInnerLabelAndIcon(result, hapInfo, distro); 1217 } 1218 } 1219 return result; 1220 } 1221 1222 /** 1223 * get label and icon for application 1224 * 1225 * @param result the result of parse app all mode 1226 * @param hapInfo hap info of entry hap 1227 * @return return the result which contains icon and label 1228 */ obtainInnerLabelAndIcon(UncompressResult result, HapInfo hapInfo, Distro distro)1229 private static UncompressResult obtainInnerLabelAndIcon(UncompressResult result, HapInfo hapInfo, Distro distro) { 1230 List<AbilityInfo> abilities = hapInfo.abilities; 1231 if ((abilities == null) || (abilities.isEmpty())) { 1232 result.setLabel(distro.moduleName); 1233 return result; 1234 } 1235 int size = 0; 1236 for (AbilityInfo info : abilities) { 1237 if (info == null) { 1238 size++; 1239 continue; 1240 } 1241 if ((info.skills == null) || (info.skills.isEmpty())) { 1242 continue; 1243 } 1244 for (SkillInfo skill : info.skills) { 1245 if (skill == null) { 1246 continue; 1247 } 1248 List<String> actions = skill.actions; 1249 List<String> entities = skill.entities; 1250 if ((!actions.isEmpty()) && (actions.contains(SYSTEM_ACTION) || actions.contains(SYSTEM_WANT_HOME))) { 1251 if ((!entities.isEmpty()) && (entities.contains(SYSTEM_ENTITY))) { 1252 result.setLabel(info.label); 1253 result.setIcon(info.icon); 1254 return result; 1255 } 1256 } 1257 } 1258 } 1259 if (size == abilities.size()) { 1260 result.setLabel(distro.moduleName); 1261 return result; 1262 } 1263 for (AbilityInfo info : abilities) { 1264 if (info != null) { 1265 result.setLabel(info.label); 1266 result.setIcon(info.icon); 1267 break; 1268 } 1269 } 1270 return result; 1271 } 1272 1273 isHarmonyProfile(String fileName)1274 private static boolean isHarmonyProfile(String fileName) { 1275 return HARMONY_PROFILE.equals(fileName); 1276 } 1277 isPackInfo(String fileName)1278 private static boolean isPackInfo(String fileName) { 1279 return PACK_INFO.equals(fileName); 1280 } 1281 getHapNameWithoutSuffix(String hapFileName)1282 private static String getHapNameWithoutSuffix(String hapFileName) { 1283 if (hapFileName == null || hapFileName.isEmpty() || hapFileName.lastIndexOf(".") == -1) { 1284 return ""; 1285 } 1286 return hapFileName.substring(0, hapFileName.lastIndexOf(".")); 1287 } 1288 unZipModuleHapFile(String srcPath)1289 private static HapZipInfo unZipModuleHapFile(String srcPath) 1290 throws BundleException, IOException { 1291 HapZipInfo hapZipInfo = new HapZipInfo(); 1292 ZipFile zipFile = null; 1293 try { 1294 File srcFile = new File(srcPath); 1295 zipFile = new ZipFile(srcFile); 1296 getProfileJson(zipFile, hapZipInfo.resourcemMap); 1297 hapZipInfo.setHarmonyProfileJsonStr(FileUtils.getFileStringFromZip(MODULE_JSON, zipFile)); 1298 hapZipInfo.setPackInfoJsonStr(FileUtils.getFileStringFromZip(PACK_INFO, zipFile)); 1299 hapZipInfo.setResDataBytes(getResourceDataFromHap(zipFile)); 1300 hapZipInfo.setHapFileName(getHapNameWithoutSuffix(srcFile.getName())); 1301 } finally { 1302 Utility.closeStream(zipFile); 1303 } 1304 return hapZipInfo; 1305 } 1306 1307 /** 1308 * uncompress from HapZipInfo 1309 * 1310 * @param hapZipInfo hap zip info 1311 * @return the parse moduleResult 1312 * @throws BundleException FileNotFoundException|IOException. 1313 */ uncompressModuleJsonInfo(HapZipInfo hapZipInfo, ModuleResult moduleResult)1314 private static void uncompressModuleJsonInfo(HapZipInfo hapZipInfo, ModuleResult moduleResult) 1315 throws BundleException { 1316 ModuleProfileInfo moduleProfileInfo = JsonUtil.parseModuleProfileInfo(hapZipInfo.getHarmonyProfileJsonStr(), 1317 hapZipInfo.getResDataBytes(), hapZipInfo.getPackInfoJsonStr(), hapZipInfo.getHapFileName(), 1318 hapZipInfo.resourcemMap); 1319 moduleProfileInfo.hapName = hapZipInfo.getHapFileName(); 1320 moduleResult.addModuleProfileInfo(moduleProfileInfo); 1321 moduleResult.moduleProfileStr.add(hapZipInfo.getHarmonyProfileJsonStr()); 1322 } 1323 1324 /** 1325 * uncompress from specified file name 1326 * 1327 * @param deviceType device type 1328 * @param srcPath source file path 1329 * @param fileName uncompress file name 1330 * @return the uncompress result 1331 * @throws BundleException FileNotFoundException|IOException. 1332 */ uncompressModule(String deviceType, String srcPath, String fileName)1333 private static ModuleResult uncompressModule(String deviceType, String srcPath, String fileName) 1334 throws BundleException { 1335 if (srcPath.isEmpty() || fileName.isEmpty()) { 1336 LOG.error("Uncompress::uncompressModule srcPath, fileName is empty!"); 1337 throw new BundleException("uncompressModule failed, srcPath or fileName is empty"); 1338 } 1339 ModuleResult moduleResult = new ModuleResult(); 1340 try { 1341 HapZipInfo hapZipInfo = unZipModuleHapFile(srcPath); 1342 uncompressModuleJsonInfo(hapZipInfo, moduleResult); 1343 if (moduleResult.packInfos.isEmpty() && !hapZipInfo.getPackInfoJsonStr().isEmpty()) { 1344 moduleResult.packInfos = JsonUtil.parsePackInfos(hapZipInfo.getPackInfoJsonStr()); 1345 } 1346 } catch (IOException exception) { 1347 moduleResult.setResult(false); 1348 LOG.error("Uncompress::uncompressModule parseMode is invalid!"); 1349 } 1350 return moduleResult; 1351 } 1352 1353 /** 1354 * uncompress module hap. 1355 * 1356 * @param deviceType indicates the device type of uncompress mode. 1357 * @param srcPath indicates the path type of hap. 1358 * @param fileName indicates json file name. 1359 * @return the uncompress result 1360 */ unCompressModuleHap(String deviceType, String srcPath, String fileName)1361 static UncompressResult unCompressModuleHap(String deviceType, String srcPath, String fileName) 1362 throws BundleException{ 1363 if (srcPath.isEmpty() || fileName.isEmpty()) { 1364 LOG.error("Uncompress::uncompress srcPath, fileName is empty!"); 1365 throw new BundleException("Uncompress failed, srcPath or fileName is empty"); 1366 } 1367 UncompressResult uncomperssResult = new UncompressResult(); 1368 ModuleResult moduleResult = new ModuleResult(); 1369 try { 1370 moduleResult = uncompressModule(deviceType, srcPath, fileName); 1371 ModuleAdaption moduleAdaption = new ModuleAdaption(); 1372 uncomperssResult = moduleAdaption.convertToUncompressResult(moduleResult); 1373 } catch (BundleException ignored) { 1374 LOG.error("Uncompress::uncompressHap Bundle exception"); 1375 uncomperssResult.setResult(false); 1376 uncomperssResult.setMessage("uncompressHap Bundle exception"); 1377 } 1378 return uncomperssResult; 1379 } 1380 /** 1381 * get all resource in profile. 1382 * 1383 * @param zipFile is the hap file 1384 * @return the parse resource result 1385 */ getProfileJson(ZipFile zipFile, HashMap<String, String> resourceMap)1386 static void getProfileJson(ZipFile zipFile, HashMap<String, String> resourceMap) throws BundleException { 1387 try { 1388 final Enumeration<? extends ZipEntry> entries = zipFile.entries(); 1389 while (entries.hasMoreElements()) { 1390 final ZipEntry entry = entries.nextElement(); 1391 if (entry.getName().contains(RESOURCE_PATH)) { 1392 String filePath = entry.getName(); 1393 String fileName = filePath.replaceAll(RESOURCE_PATH, ""); 1394 String fileContent = FileUtils.getFileStringFromZip(filePath, zipFile); 1395 resourceMap.put(fileName, fileContent); 1396 } 1397 } 1398 } catch (IOException e) { 1399 LOG.error("Uncompress::getProfileJson IOException"); 1400 throw new BundleException("Uncompress::getProfileJson failed"); 1401 } 1402 } 1403 1404 /** 1405 * uncompress module hap. 1406 * 1407 * @param deviceType indicates the deviceType of parse hap. 1408 * @param input the InputStream about the app package. 1409 * @param fileName the file name of json file. 1410 * @return the uncompress result 1411 */ uncompressModuleHapByInput(String deviceType, InputStream input, String fileName, String hapName)1412 static UncompressResult uncompressModuleHapByInput(String deviceType, 1413 InputStream input, String fileName, String hapName) { 1414 UncompressResult uncompressResult = new UncompressResult(); 1415 ModuleResult moduleResult = new ModuleResult(); 1416 try { 1417 moduleResult = uncompressModuleByInput(deviceType, input, MODULE_JSON, hapName); 1418 ModuleAdaption moduleAdaption = new ModuleAdaption(); 1419 uncompressResult = moduleAdaption.convertToUncompressResult(moduleResult); 1420 } catch (BundleException ignored) { 1421 LOG.error("Uncompress::uncompressHapByInput Bundle exception"); 1422 uncompressResult.setResult(false); 1423 uncompressResult.setMessage("uncompressHapByInput Bundle exception"); 1424 } 1425 return uncompressResult; 1426 } 1427 1428 /** 1429 * unzip module hap from zip file. 1430 * 1431 * @param input Indicates the InputStream about the package. 1432 * @return Return the uncomperss result of parseHap 1433 */ unZipModuleHapFileFromInputStream(InputStream input)1434 private static HapZipInfo unZipModuleHapFileFromInputStream(InputStream input) throws BundleException { 1435 BufferedInputStream bufIn = null; 1436 ZipInputStream zipIn = null; 1437 BufferedReader bufferedReader = null; 1438 HapZipInfo hapZipInfo = new HapZipInfo(); 1439 try { 1440 ZipEntry entry = null; 1441 bufIn = new BufferedInputStream(input); 1442 zipIn = new ZipInputStream(bufIn); 1443 while ((entry = zipIn.getNextEntry()) != null) { 1444 if (entry.getName().toLowerCase().endsWith(RESOURCE_INDEX)) { 1445 hapZipInfo.setResDataBytes(getByte(zipIn)); 1446 continue; 1447 } 1448 if (isPackInfo(entry.getName())) { 1449 bufferedReader = new BufferedReader(new InputStreamReader(zipIn)); 1450 hapZipInfo.setPackInfoJsonStr(readStringFromInputStream(zipIn, bufferedReader)); 1451 continue; 1452 } 1453 if (MODULE_JSON.equals(entry.getName())) { 1454 bufferedReader = new BufferedReader(new InputStreamReader(zipIn)); 1455 hapZipInfo.setHarmonyProfileJsonStr(readStringFromInputStream(zipIn, bufferedReader)); 1456 } 1457 if (entry.getName().contains(RESOURCE_PATH)) { 1458 bufferedReader = new BufferedReader(new InputStreamReader(zipIn)); 1459 String filePath = entry.getName(); 1460 String fileName = filePath.replaceAll(RESOURCE_PATH, ""); 1461 String fileContent = readStringFromInputStream(zipIn, bufferedReader); 1462 hapZipInfo.pushResourceMap(fileName, fileContent); 1463 } 1464 } 1465 } catch (BundleException | IOException e) { 1466 LOG.error("unZipModuleHapFileFromInputStream failed!"); 1467 throw new BundleException("unZipModuleHapFileFromInputStream failed!"); 1468 } finally { 1469 Utility.closeStream(bufferedReader); 1470 Utility.closeStream(bufIn); 1471 Utility.closeStream(zipIn); 1472 } 1473 return hapZipInfo; 1474 } 1475 1476 /** 1477 * Parse the hap type. 1478 * 1479 * @param hapPath Indicates the hap path. 1480 * @param compressResult Indicates the result of parse hap. 1481 * @return Return the type result of isModuleHap 1482 */ isModuleHap(String hapPath, UncompressResult compressResult)1483 public static boolean isModuleHap(String hapPath, UncompressResult compressResult) { 1484 ZipFile zipFile = null; 1485 try { 1486 zipFile = new ZipFile(new File(hapPath)); 1487 final Enumeration<? extends ZipEntry> entries = zipFile.entries(); 1488 while (entries.hasMoreElements()) { 1489 final ZipEntry entry = entries.nextElement(); 1490 if (MODULE_JSON.equals(entry.getName())) { 1491 return true; 1492 } 1493 } 1494 } catch (FileNotFoundException ignored) { 1495 LOG.error("Uncompress::isModuleHap file not found exception"); 1496 compressResult.setResult(false); 1497 compressResult.setMessage("judge is module failed"); 1498 } catch (IOException exception) { 1499 LOG.error("Uncompress::isModuleHap io exception: " + exception.getMessage()); 1500 compressResult.setResult(false); 1501 compressResult.setMessage("judge is module failed"); 1502 } finally { 1503 Utility.closeStream(zipFile); 1504 } 1505 return false; 1506 } 1507 1508 /** 1509 * Parse the hap type. 1510 * 1511 * @param input Indicates the hap FileInputStream. 1512 * @return Return the type result of isModuleHap. 1513 */ isModuleInput(InputStream input)1514 public static boolean isModuleInput(InputStream input) throws BundleException { 1515 BufferedInputStream bufIn = null; 1516 ZipInputStream zipIn = null; 1517 BufferedReader bufferedReader = null; 1518 try { 1519 ZipEntry entry = null; 1520 bufIn = new BufferedInputStream(input); 1521 zipIn = new ZipInputStream(bufIn); 1522 while((entry = zipIn.getNextEntry()) != null) { 1523 if (entry.getName().toLowerCase().endsWith(MODULE_JSON)) { 1524 return true; 1525 } 1526 } 1527 } catch (IOException ignored) { 1528 LOG.error("Uncompress::isModuleHap judge failed!"); 1529 throw new BundleException("Uncompress::isModuleHap judge failed!"); 1530 } finally { 1531 Utility.closeStream(bufferedReader); 1532 Utility.closeStream(bufIn); 1533 Utility.closeStream(zipIn); 1534 } 1535 return false; 1536 } 1537 1538 /** 1539 * create file output stream from InputStream . 1540 * 1541 * @param stream Indicates the input stream of hap. 1542 * @param file Indicates the temp file to save input stream. 1543 */ writeToTempFile(InputStream stream, File file)1544 static void writeToTempFile(InputStream stream, File file) throws BundleException { 1545 FileOutputStream fileOutputStream = null; 1546 try { 1547 if (file == null) { 1548 LOG.error("file not exist!"); 1549 } 1550 fileOutputStream = new FileOutputStream(file); 1551 int bytesRead = 0; 1552 byte[] buffer = new byte[1024]; 1553 while ((bytesRead = stream.read(buffer)) != -1) { 1554 fileOutputStream.write(buffer, 0, bytesRead); 1555 } 1556 } catch (IOException e) { 1557 LOG.error("writeToTempFile failed!"); 1558 throw new BundleException("writeToTempFile failed!"); 1559 } finally { 1560 Utility.closeStream(fileOutputStream); 1561 } 1562 } 1563 1564 /** 1565 * copy rpcid.sc file. 1566 * 1567 * @param srcFile Indicates the path of hap. 1568 * @param rpcidPath Indicates the output path of rpcid.sc file. 1569 */ getRpcidFromHap(String srcFile, String rpcidPath)1570 static void getRpcidFromHap(String srcFile, String rpcidPath) throws BundleException { 1571 ZipFile zipFile = null; 1572 InputStream inputStream = null; 1573 FileOutputStream outputStream = null; 1574 try { 1575 zipFile = new ZipFile(srcFile); 1576 String filePath = null; 1577 final Enumeration<? extends ZipEntry> entries = zipFile.entries(); 1578 while (entries.hasMoreElements()) { 1579 final ZipEntry entry = entries.nextElement(); 1580 if (RPCID_SC.equals(entry.getName())) { 1581 filePath = entry.getName(); 1582 break; 1583 } 1584 } 1585 if (filePath != null) { 1586 File rpcidFile = new File(rpcidPath, RPCID_SC); 1587 if (rpcidFile.getParentFile() != null && !rpcidFile.getParentFile().exists()) { 1588 rpcidFile.getParentFile().mkdirs(); 1589 } 1590 ZipEntry rpcidEntry = zipFile.getEntry(filePath); 1591 inputStream = zipFile.getInputStream(rpcidEntry); 1592 byte[] buffer = new byte[1024]; 1593 int noBytes = 0; 1594 outputStream = new FileOutputStream(rpcidFile); 1595 while((noBytes = inputStream.read(buffer)) != -1) { 1596 outputStream.write(buffer, 0, noBytes); 1597 } 1598 } else { 1599 LOG.error("Uncompress::getRpcidFromHap hap has no rpcid.sc file"); 1600 throw new BundleException("Uncompress::getRpcidFromHap hap has no rpcid.sc file"); 1601 } 1602 } catch (IOException e) { 1603 LOG.error("Uncompress::getRpcidFromHap IOException " + e.getMessage()); 1604 throw new BundleException("Uncompress::getRpcidFromHap failed"); 1605 } finally { 1606 Utility.closeStream(zipFile); 1607 Utility.closeStream(inputStream); 1608 Utility.closeStream(outputStream); 1609 } 1610 } 1611 1612 /** 1613 * parse resource.index file. 1614 * 1615 * @param srcPath Indicates the path of hap. 1616 */ getResourceFromHap(String srcPath)1617 static List<ResourceIndexResult> getResourceFromHap(String srcPath) throws BundleException, IOException { 1618 ZipFile zipFile = null; 1619 try { 1620 File srcFile = new File(srcPath); 1621 zipFile = new ZipFile(srcFile); 1622 byte[] data = getResourceDataFromHap(zipFile); 1623 return ResourcesParser.getAllDataItem(data); 1624 } finally { 1625 Utility.closeStream(zipFile); 1626 } 1627 } 1628 1629 /** 1630 * uncompress appqf file. 1631 * 1632 * @param utility is the common args for input. 1633 * @throws BundleException if uncompress failed. 1634 */ uncompressAPPQFFile(Utility utility)1635 private static void uncompressAPPQFFile(Utility utility) throws BundleException { 1636 ZipFile zipFile = null; 1637 try { 1638 zipFile = new ZipFile(new File(utility.getAPPQFPath())); 1639 int entriesNum = 0; 1640 for (Enumeration<? extends ZipEntry> entries = zipFile.entries(); entries.hasMoreElements();) { 1641 entriesNum++; 1642 ZipEntry entry = entries.nextElement(); 1643 if (entry == null) { 1644 continue; 1645 } 1646 String filePath = utility.getOutPath() + File.separator + entry.getName(); 1647 if (!FileUtils.matchPattern(filePath)) { 1648 LOG.error("uncompressAPPQFFile: Input invalid file" + filePath); 1649 throw new BundleException("uncompressAPPQFFile: Input invalid file" + filePath); 1650 } 1651 File destFile = new File(filePath); 1652 if (destFile != null && destFile.getParentFile() != null && !destFile.getParentFile().exists()) { 1653 destFile.getParentFile().mkdirs(); 1654 } 1655 dataTransfer(zipFile, entry, destFile); 1656 } 1657 } catch (FileNotFoundException ignored) { 1658 LOG.error("Uncompress::uncompressAPPQFFile file not found exception"); 1659 throw new BundleException("Uncompress::uncompressAPPQFFile file not found"); 1660 } catch (IOException exception) { 1661 LOG.error("Uncompress::uncompressAPPQFFile io exception"); 1662 throw new BundleException("Uncompress::uncompressAPPQFFile io exception"); 1663 } finally { 1664 Utility.closeStream(zipFile); 1665 } 1666 } 1667 1668 /** 1669 * parse appqf file, . 1670 * 1671 * @param appqfPath is the path of appqf file. 1672 * @throws BundleException if uncompress failed. 1673 * @throws IOException if IOException happened. 1674 */ parseAPPQFFile(String appqfPath)1675 public static List<HQFInfo> parseAPPQFFile(String appqfPath) throws BundleException { 1676 List<String> patchList = new ArrayList<>(); 1677 ZipFile zipFile = null; 1678 InputStream stream = null; 1679 ZipInputStream zipInputStream = null; 1680 try { 1681 zipFile = new ZipFile(appqfPath); 1682 Enumeration<? extends ZipEntry> entries = zipFile.entries(); 1683 while (entries.hasMoreElements()) { 1684 ZipEntry appqfEntry = entries.nextElement(); 1685 stream = zipFile.getInputStream(appqfEntry); 1686 if (!appqfEntry.getName().endsWith(HQF_SUFFIX)) { 1687 continue; 1688 } 1689 zipInputStream = new ZipInputStream(stream); 1690 String patchJson = readPatchJson(zipInputStream); 1691 if (patchJson == null) { 1692 continue; 1693 } 1694 patchList.add(patchJson); 1695 } 1696 } catch (IOException e) { 1697 LOG.error("parseAPPQFFile failed!"); 1698 throw new BundleException("parseAPPQFFile failed!"); 1699 } finally { 1700 Utility.closeStream(zipFile); 1701 Utility.closeStream(stream); 1702 Utility.closeStream(zipInputStream); 1703 } 1704 return parsePatchJson(patchList); 1705 } 1706 readPatchJson(ZipInputStream zipInputStream)1707 private static String readPatchJson(ZipInputStream zipInputStream) throws BundleException { 1708 String patchJson = null; 1709 ZipEntry hqfEntry; 1710 try { 1711 while ((hqfEntry = zipInputStream.getNextEntry()) != null) { 1712 if (!PATCH_JSON.equals(hqfEntry.getName())) { 1713 continue; 1714 } 1715 patchJson = new BufferedReader(new InputStreamReader(zipInputStream, 1716 StandardCharsets.UTF_8)).lines().parallel() 1717 .collect(Collectors.joining(System.lineSeparator())); 1718 } 1719 } catch (IOException e) { 1720 LOG.error("readPatchJson failed!"); 1721 throw new BundleException("readPatchJson failed!"); 1722 } 1723 return patchJson; 1724 } 1725 parsePatchJson(List<String> patchList)1726 private static List<HQFInfo> parsePatchJson(List<String> patchList) throws BundleException { 1727 List<HQFInfo> hqfInfoList = new ArrayList<>(); 1728 for (String patchJson : patchList) { 1729 hqfInfoList.add(JsonUtil.parsePatch(patchJson)); 1730 } 1731 return hqfInfoList; 1732 } 1733 comparePackAndProfile(PackInfo packInfo, ProfileInfo profileInfo)1734 private static boolean comparePackAndProfile(PackInfo packInfo, ProfileInfo profileInfo) { 1735 if (profileInfo.hapName.replace(HAP_SUFFIXI, "").equals(packInfo.name.replace(HAP_SUFFIXI, ""))) { 1736 return true; 1737 } 1738 if (profileInfo.hapName.replace(HSP_SUFFIX, "").equals(packInfo.name.replace(HSP_SUFFIX, ""))) { 1739 return true; 1740 } 1741 return false; 1742 } 1743 } 1744