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 import java.nio.file.attribute.FileTime; 31 32 import java.util.ArrayList; 33 import java.util.Enumeration; 34 import java.util.HashMap; 35 import java.util.List; 36 import java.util.Locale; 37 import java.util.stream.Collectors; 38 import java.util.zip.CRC32; 39 import java.util.zip.CheckedOutputStream; 40 import java.util.zip.ZipEntry; 41 import java.util.zip.ZipFile; 42 import java.util.zip.ZipInputStream; 43 import java.util.zip.ZipOutputStream; 44 45 /** 46 * bundle uncompress. 47 * 48 */ 49 public class Uncompress { 50 private static final String HAP_SUFFIX = ".hap"; 51 private static final String APK_SUFFIX = ".apk"; 52 private static final String JSON_SUFFIX = ".json"; 53 54 private static final String PACK_INFO = "pack.info"; 55 private static final String HARMONY_PROFILE = "config.json"; 56 private static final String MODULE_JSON = "module.json"; 57 private static final String RESOURCE_INDEX = "resources.index"; 58 private static final String RPCID_SC = "rpcid.sc"; 59 private static final String LINUX_FILE_SEPARATOR = "/"; 60 private static final String TEMP_PATH = "temp"; 61 private static final String HAP_SUFFIXI = ".hap"; 62 private static final String ENTRY_TYPE = "entry"; 63 private static final String SYSTEM_ACTION = "action.system.home"; 64 private static final String SYSTEM_WANT_HOME = "ohos.want.action.home"; 65 private static final String SYSTEM_ENTITY = "entity.system.home"; 66 private static final int READ_BUFFER_SIZE = 1024; 67 private static final int BUFFER_SIZE = 10 * 1024; 68 private static final long FILE_TIME = 1546272000000L; 69 private static final String LIBS_DIR_NAME = "libs"; 70 private static final String CUT_ENTRY_FILENAME = "cut_entry.apk"; 71 private static final String SO_SUFFIX = ".so"; 72 private static final String RESOURCE_PATH = "resources/base/profile/"; 73 private static final String TRUE = "true"; 74 private static final String HQF_SUFFIX = ".hqf"; 75 private static final String PATCH_JSON = "patch.json"; 76 private static final String HAP_PREFIX = "HAP"; 77 private static final String HSP_SUFFIX = ".hsp"; 78 79 private static final Log LOG = new Log(Uncompress.class.toString()); 80 81 /** 82 * unpackage entrance. 83 * 84 * @param utility common data 85 * @return unpackageProcess if unpackage succeed 86 */ unpackageProcess(Utility utility)87 static boolean unpackageProcess(Utility utility) { 88 if (utility == null) { 89 LOG.error("Uncompress::unpackageProcess utility is null."); 90 return false; 91 } 92 boolean unpackageResult = true; 93 File destFile = new File(utility.getOutPath()); 94 95 if (!destFile.exists()) { 96 if (!destFile.mkdirs()) { 97 LOG.error("Uncompress::unpackageProcess create out file directory failed!"); 98 return false; 99 } 100 } 101 try { 102 if (!Utility.MODE_HAP.equals(utility.getMode()) || !TRUE.equals(utility.getRpcid())) { 103 if (!utility.getForceRewrite().isEmpty() && "true".equals(utility.getForceRewrite())) { 104 File outPath = new File(utility.getOutPath()); 105 deleteFile(outPath); 106 outPath.mkdirs(); 107 } 108 } 109 switch (utility.getMode()) { 110 case Utility.MODE_HAP: 111 unpackageHapMode(utility); 112 break; 113 case Utility.MODE_HAR: 114 dataTransferAllFiles(utility.getHarPath(), utility.getOutPath()); 115 break; 116 case Utility.MODE_APP: 117 dataTransferFilesByApp(utility, utility.getAppPath(), utility.getOutPath()); 118 break; 119 case Utility.MODE_APPQF: 120 uncompressAPPQFFile(utility); 121 break; 122 case Utility.MODE_HSP: 123 dataTransferAllFiles(utility.getHspPath(), utility.getOutPath()); 124 break; 125 default: 126 LOG.error("Uncompress::unpackageProcess input wrong type!"); 127 throw new BundleException("Uncompress::unpackageProcess input wrong type!"); 128 } 129 } catch (BundleException ignored) { 130 unpackageResult = false; 131 LOG.error("Uncompress::unpackageProcess Bundle exception"); 132 } 133 // return uncompress information. 134 if (!unpackageResult) { 135 LOG.error("Uncompress::unpackageProcess unpackage failed!"); 136 } 137 return unpackageResult; 138 } 139 140 /** 141 * unpack hap. 142 * 143 * @param utility common data 144 */ unpackageHapMode(Utility utility)145 static void unpackageHapMode(Utility utility) throws BundleException { 146 if (!Utility.MODE_HAP.equals(utility.getMode())) { 147 throw new BundleException("Uncompress::unpackageHapMode input wrong unpack mode"); 148 } 149 try { 150 if (TRUE.equals(utility.getRpcid())) { 151 getRpcidFromHap(utility.getHapPath(), utility.getOutPath()); 152 return; 153 } 154 if (TRUE.equals(utility.getUnpackApk())) { 155 unzip(utility, utility.getHapPath(), utility.getOutPath(), APK_SUFFIX); 156 String[] temp = utility.getHapPath().replace("\\", "/").split("/"); 157 String hapName = temp[temp.length - 1]; 158 repackHap(utility.getHapPath(), utility.getOutPath(), hapName, utility.getUnpackApk()); 159 } else { 160 dataTransferAllFiles(utility.getHapPath(), utility.getOutPath()); 161 } 162 } catch (BundleException e) { 163 LOG.error("Uncompress::unpackageHapMode failed"); 164 throw new BundleException("Uncompress::unpackageHapMode failed"); 165 } 166 } 167 168 /** 169 * uncompress app. 170 * 171 * @param utility common data 172 * @return the uncompress result 173 */ uncompressAppByPath(Utility utility)174 static UncompressResult uncompressAppByPath(Utility utility) { 175 UncompressResult compressResult = new UncompressResult(); 176 InputStream input = null; 177 String srcPath = utility.getAppPath(); 178 String parseMode = utility.getParseMode(); 179 180 try { 181 if (UncompressEntrance.PARSE_MODE_HAPLIST.equals(parseMode)) { 182 compressResult = uncompress(utility.getDeviceType(), srcPath, PACK_INFO); 183 } else if (UncompressEntrance.PARSE_MODE_HAPINFO.equals(parseMode)) { 184 compressResult = uncompressHapAndHspFromAppPath(srcPath, utility); 185 } else if (UncompressEntrance.PARSE_MODE_ALL.equals(parseMode)) { 186 compressResult = uncompressAllAppByPath(srcPath); 187 } else { 188 LOG.error("Uncompress::uncompressApp parseMode is invalid!"); 189 compressResult.setResult(false); 190 compressResult.setMessage("ParseApp parseMode is invalid"); 191 } 192 } catch (BundleException e) { 193 LOG.error("Uncompress::uncompressApp Bundle exception"); 194 compressResult.setResult(false); 195 compressResult.setMessage("ParseApp Bundle exception"); 196 } finally { 197 Utility.closeStream(input); 198 } 199 return compressResult; 200 } 201 uncompressHapAndHspFromAppPath( String srcPath, Utility utility)202 private static UncompressResult uncompressHapAndHspFromAppPath( 203 String srcPath, Utility utility) throws BundleException { 204 UncompressResult result = new UncompressResult(); 205 String hapName = utility.getHapName(); 206 if (!hapName.toLowerCase(Locale.ENGLISH).endsWith(HAP_SUFFIX) 207 && !hapName.toLowerCase(Locale.ENGLISH).endsWith(HSP_SUFFIX)) { 208 hapName += HAP_SUFFIX; 209 } 210 ZipFile appFile = null; 211 ZipEntry entry = null; 212 InputStream stream = null; 213 try { 214 appFile = new ZipFile(srcPath); 215 Enumeration<? extends ZipEntry> entries = appFile.entries(); 216 while (entries.hasMoreElements()) { 217 entry = entries.nextElement(); 218 stream = appFile.getInputStream(entry); 219 if (!hapName.equals(entry.getName().toLowerCase(Locale.ENGLISH))) { 220 continue; 221 } 222 UncompressResult hapInfo = uncompressHapByStream("", stream, hapName); 223 if (hapInfo.getProfileInfos() != null && hapInfo.getProfileInfos().size() > 0) { 224 result.addProfileInfo(hapInfo.getProfileInfos().get(0)); 225 result.addProfileInfoStr(hapInfo.getProfileInfosStr().get(0)); 226 } 227 break; 228 } 229 } catch (IOException | BundleException e) { 230 LOG.error("uncompressHapFromAppPath failed!"); 231 throw new BundleException("uncompressHapFromAppPath failed!"); 232 } finally { 233 Utility.closeStream(appFile); 234 Utility.closeStream(stream); 235 } 236 return result; 237 } 238 uncompressAllAppByPath(String srcPath)239 private static UncompressResult uncompressAllAppByPath(String srcPath) throws BundleException { 240 UncompressResult result = new UncompressResult(); 241 ZipFile appFile = null; 242 ZipEntry entry = null; 243 InputStream stream = null; 244 try { 245 appFile = new ZipFile(srcPath); 246 Enumeration<? extends ZipEntry> entries = appFile.entries(); 247 while (entries.hasMoreElements()) { 248 entry = entries.nextElement(); 249 stream = appFile.getInputStream(entry); 250 if (PACK_INFO.equals(entry.getName().toLowerCase(Locale.ENGLISH))) { 251 String packInfo = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8)) 252 .lines().parallel().collect(Collectors.joining(System.lineSeparator())); 253 List<PackInfo> packInfos = JsonUtil.parseHapList("", packInfo); 254 result.setPackInfoStr(packInfo); 255 result.setPackInfos(packInfos); 256 } 257 if (entry.getName().toLowerCase(Locale.ENGLISH).endsWith(HAP_SUFFIX) 258 || entry.getName().toLowerCase(Locale.ENGLISH).endsWith(HSP_SUFFIX)) { 259 UncompressResult hapInfo = uncompressHapByStream("", stream, entry.getName()); 260 if (hapInfo.getProfileInfos() != null && hapInfo.getProfileInfos().size() > 0) { 261 result.addProfileInfo(hapInfo.getProfileInfos().get(0)); 262 result.addProfileInfoStr(hapInfo.getProfileInfosStr().get(0)); 263 } 264 } 265 } 266 result = checkParseAllResult(result); 267 result = obtainLabelAndIcon(result); 268 } catch (IOException | BundleException e) { 269 LOG.error("uncompressAllAppByPath failed!"); 270 throw new BundleException("uncompressAllAppByPath failed!"); 271 } finally { 272 Utility.closeStream(appFile); 273 Utility.closeStream(stream); 274 } 275 return result; 276 } 277 278 279 /** 280 * uncompress app. 281 * 282 * @param utility common data 283 * @param input the InputStream about the app package. 284 * @return the uncompress result 285 */ uncompressAppByInput(Utility utility, InputStream input)286 static UncompressResult uncompressAppByInput(Utility utility, InputStream input) { 287 UncompressResult compressResult = new UncompressResult(); 288 String parseMode = utility.getParseMode(); 289 try { 290 if (!parseMode.isEmpty() && UncompressEntrance.PARSE_MODE_HAPLIST.equals(parseMode)) { 291 compressResult = uncompressByInput(utility.getDeviceType(), input, PACK_INFO, ""); 292 } else if (!parseMode.isEmpty() && UncompressEntrance.PARSE_MODE_HAPINFO.equals(parseMode)) { 293 compressResult = uncompressHapFromAppStream(utility.getDeviceType(), input, utility.getHapName()); 294 } else if (!parseMode.isEmpty() && UncompressEntrance.PARSE_MODE_ALL.equals(parseMode)) { 295 compressResult = uncompressAllFromAppStream(input); 296 } else { 297 LOG.error("Uncompress::uncompressAppByInput parseMode is invalid!"); 298 compressResult.setResult(false); 299 compressResult.setMessage("ParseApp parseMode is invalid"); 300 } 301 } catch (BundleException exception) { 302 LOG.error("Uncompress::uncompressAppByInput Bundle exception"); 303 compressResult.setResult(false); 304 compressResult.setMessage("ParseApp Bundle exception"); 305 } 306 return compressResult; 307 } 308 uncompressHapFromAppStream(String deviceType, InputStream stream, String fileName)309 private static UncompressResult uncompressHapFromAppStream(String deviceType, InputStream stream, String fileName) 310 throws BundleException { 311 String hapFile = fileName; 312 if (!fileName.toLowerCase(Locale.ENGLISH).endsWith(HAP_SUFFIX) 313 && !fileName.toLowerCase(Locale.ENGLISH).endsWith(HSP_SUFFIX)) { 314 hapFile += HAP_SUFFIX; 315 } 316 UncompressResult result = new UncompressResult(); 317 ZipInputStream zipInputStream = null; 318 try { 319 zipInputStream = new ZipInputStream(stream); 320 ZipEntry appEntry; 321 while ((appEntry = zipInputStream.getNextEntry()) != null) { 322 if (appEntry.getName().toLowerCase(Locale.ENGLISH).equals(hapFile)) { 323 result = uncompressHapByStream("", zipInputStream, appEntry.getName()); 324 } 325 } 326 } catch (IOException e) { 327 LOG.error("uncompressHapFromAppStream failed!"); 328 throw new BundleException("uncompressHapFromAppStream failed!"); 329 } finally { 330 Utility.closeStream(zipInputStream); 331 } 332 return result; 333 } 334 uncompressAllFromAppStream(InputStream stream)335 private static UncompressResult uncompressAllFromAppStream(InputStream stream) throws BundleException { 336 UncompressResult result = new UncompressResult(); 337 ZipInputStream zipInputStream = null; 338 try { 339 zipInputStream = new ZipInputStream(stream); 340 ZipEntry entry; 341 while ((entry = zipInputStream.getNextEntry()) != null) { 342 if (PACK_INFO.equals(entry.getName().toLowerCase(Locale.ENGLISH))) { 343 String packInfo = new BufferedReader(new InputStreamReader(zipInputStream, 344 StandardCharsets.UTF_8)).lines().parallel() 345 .collect(Collectors.joining(System.lineSeparator())); 346 List<PackInfo> packInfos = JsonUtil.parseHapList("", packInfo); 347 result.setPackInfoStr(packInfo); 348 result.setPackInfos(packInfos); 349 } 350 if (entry.getName().toLowerCase(Locale.ENGLISH).endsWith(HAP_SUFFIX) 351 || entry.getName().toLowerCase(Locale.ENGLISH).endsWith(HSP_SUFFIX)) { 352 UncompressResult hapResult = uncompressHapByStream("", zipInputStream, entry.getName()); 353 if (hapResult.getProfileInfos() != null && hapResult.getProfileInfos().size() > 0) { 354 result.addProfileInfo(hapResult.getProfileInfos().get(0)); 355 result.addProfileInfoStr(hapResult.getProfileInfosStr().get(0)); 356 } 357 } 358 } 359 result = checkParseAllResult(result); 360 result = obtainLabelAndIcon(result); 361 } catch (IOException | BundleException e) { 362 LOG.error("uncompressAllFromAppStream failed!"); 363 throw new BundleException("uncompressAllFromAppStream failed!"); 364 } finally { 365 Utility.closeStream(zipInputStream); 366 } 367 return result; 368 } 369 370 /** 371 * uncompress hap. 372 * 373 * @param utility common data 374 * @return the uncompress result 375 */ uncompressHap(Utility utility)376 static UncompressResult uncompressHap(Utility utility) { 377 UncompressResult compressResult = new UncompressResult(); 378 try { 379 compressResult = uncompressHapByPath(utility.getDeviceType(), utility.getHapPath()); 380 } catch (BundleException ignored) { 381 LOG.error("Uncompress::uncompressHap Bundle exception"); 382 compressResult.setResult(false); 383 compressResult.setMessage("uncompressHap Bundle exception"); 384 } 385 return compressResult; 386 } 387 388 /** 389 * uncompress hap by path, it can adapt stage module and fa module. 390 * 391 * @param deviceType indicates the device type of parse type. 392 * @param hapPath indicates the hap path of hap. 393 * @return the uncompress result 394 */ uncompressHapByPath(String deviceType, String hapPath)395 static UncompressResult uncompressHapByPath(String deviceType, String hapPath) throws BundleException { 396 UncompressResult compressResult = new UncompressResult(); 397 try { 398 if (isModuleHap(hapPath, compressResult)) { 399 compressResult = unCompressModuleHap(deviceType, hapPath, MODULE_JSON); 400 } else { 401 compressResult = uncompress(deviceType, hapPath, HARMONY_PROFILE); 402 compressResult = obtainLabelAndIcon(compressResult); 403 } 404 } catch (BundleException e) { 405 LOG.error("Uncompress::uncompressHapByPath Bundle exception"); 406 throw new BundleException("Uncompress::uncompressHapByPath failed"); 407 } 408 return compressResult; 409 } 410 411 /** 412 * uncompress hap. 413 * 414 * @param utility common data 415 * @param input the InputStream about the app package. 416 * @return the uncompress result 417 */ uncompressHapByInput(Utility utility, InputStream input)418 static UncompressResult uncompressHapByInput(Utility utility, InputStream input) { 419 UncompressResult compressResult = new UncompressResult(); 420 try { 421 compressResult = uncompressHapByStream(utility.getDeviceType(), input, ""); 422 } catch (BundleException ignored) { 423 LOG.error("Uncompress::uncompressHapByInput Bundle exception"); 424 compressResult.setResult(false); 425 compressResult.setMessage("uncompressHapByInput Bundle exception"); 426 } 427 return compressResult; 428 } 429 430 /** 431 * uncompress hap by InputStream, it can adapt stage module and fa module. 432 * 433 * @param deviceType indicates the device type of parse type. 434 * @param stream indicates the input stream of hap. 435 * @return the uncompress result 436 */ uncompressHapByStream(String deviceType, InputStream stream, String hapName)437 static UncompressResult uncompressHapByStream(String deviceType, InputStream stream, 438 String hapName) throws BundleException { 439 UncompressResult compressResult = new UncompressResult(); 440 compressResult = uncompressHapByBigStream(deviceType, stream, hapName); 441 return compressResult; 442 } 443 uncompressHapByBigStream(String deviceType, InputStream stream, String hapName)444 static UncompressResult uncompressHapByBigStream(String deviceType, InputStream stream, String hapName) 445 throws BundleException { 446 UncompressResult compressResult = new UncompressResult(); 447 InputStream fileStream = null; 448 InputStream parseStream = null; 449 File file = null; 450 try { 451 String releativePath = System.getProperty("user.dir"); 452 File directory = new File(releativePath); 453 file = File.createTempFile(HAP_PREFIX, HAP_SUFFIX, directory); 454 writeToTempFile(stream, file); 455 fileStream = new FileInputStream(file); 456 boolean isModule = false; 457 if (isModuleInput(fileStream)) { 458 isModule = true; 459 } 460 parseStream = new FileInputStream(file); 461 if (isModule) { 462 compressResult = uncompressModuleHapByInput(deviceType, parseStream, MODULE_JSON, hapName); 463 } else { 464 compressResult = uncompressByInput(deviceType, parseStream, HARMONY_PROFILE, hapName); 465 compressResult = obtainLabelAndIcon(compressResult); 466 } 467 } catch (IOException e) { 468 LOG.error("uncompressHapByBigStream failed for IO exception!"); 469 throw new BundleException("uncompressHapByBigStream failed for IO exception!"); 470 } finally { 471 Utility.closeStream(fileStream); 472 Utility.closeStream(parseStream); 473 if (file != null) { 474 FileUtils.deleteFile(file.getPath()); 475 } 476 } 477 return compressResult; 478 } 479 480 /** 481 * unzip process 482 * 483 * @param utility common data 484 * @param srcPath source file path 485 * @param destDirPath destination file path 486 * @param suffix suffix for judgment 487 * @throws BundleException FileNotFoundException|IOException. 488 */ unzip(Utility utility, String srcPath, String destDirPath, String suffix)489 private static void unzip(Utility utility, String srcPath, String destDirPath, String suffix) 490 throws BundleException { 491 if (utility == null) { 492 LOG.error("Uncompress::unzip utility is null!"); 493 throw new BundleException("Unzip failed, utility is null"); 494 } 495 496 if (srcPath.isEmpty() || !UncompressVerify.isPathValid(srcPath, true, "")) { 497 LOG.error("Uncompress::unzip srcPath is invalid!"); 498 throw new BundleException("Unzip failed, srcPath is invalid"); 499 } 500 501 if (destDirPath.isEmpty() || !UncompressVerify.isPathValid(destDirPath, false, null)) { 502 LOG.error("Uncompress::unzip destDirPath is invalid!"); 503 throw new BundleException("Unzip failed, destDirPath is invalid"); 504 } 505 unzipFromFile(utility, srcPath, destDirPath, suffix); 506 } 507 508 /** 509 * unzip process from the file 510 * 511 * @param utility common data 512 * @param srcPath source file path 513 * @param destDirPath destination file path 514 * @param suffix suffix for judgment 515 * @throws BundleException FileNotFoundException|IOException. 516 */ unzipFromFile(Utility utility, String srcPath, String destDirPath, String suffix)517 private static void unzipFromFile(Utility utility, String srcPath, String destDirPath, String suffix) 518 throws BundleException { 519 ZipFile zipFile = null; 520 String hapNames = ""; 521 try { 522 zipFile = new ZipFile(new File(srcPath)); 523 if (utility != null && !utility.getDeviceType().isEmpty() 524 && (HAP_SUFFIX.equals(suffix) || HSP_SUFFIX.equals(suffix))) { 525 List<PackInfo> packInfos = uncompress(utility.getDeviceType(), srcPath, PACK_INFO).getPackInfos(); 526 for (PackInfo packinfo : packInfos) { 527 hapNames += packinfo.name + ","; 528 } 529 } 530 531 int entriesNum = 0; 532 for (Enumeration<? extends ZipEntry> entries = zipFile.entries(); entries.hasMoreElements(); ) { 533 entriesNum++; 534 ZipEntry entry = entries.nextElement(); 535 String entryName = ""; 536 if (entry == null || entry.getName().isEmpty()) { 537 continue; 538 } 539 if (entry.getName().toLowerCase().endsWith(CUT_ENTRY_FILENAME) && 540 "false".equals(utility.getUnpackCutEntryApk())) { 541 continue; 542 } 543 entryName = entry.getName(); 544 if (!entryName.toLowerCase(Locale.ENGLISH).endsWith(suffix) || 545 (!hapNames.isEmpty() && !hapNames.contains(entryName.replace(suffix, "")))) { 546 continue; 547 } 548 String tempDir = destDirPath.replace(File.separator, LINUX_FILE_SEPARATOR); 549 if (HAP_SUFFIX.equals(suffix) && "true".equals(utility.getUnpackApk())) { 550 tempDir = tempDir + LINUX_FILE_SEPARATOR + entryName.replace(suffix, ""); 551 File destFileDir = new File(tempDir); 552 if (!destFileDir.exists()) { 553 destFileDir.mkdir(); 554 } 555 } 556 if (APK_SUFFIX.equals(suffix) && "true".equals(utility.getUnpackApk()) 557 && entryName.contains(LINUX_FILE_SEPARATOR)) { 558 // only unpack shell apk which in the root directory 559 continue; 560 } 561 String tempPath = tempDir + LINUX_FILE_SEPARATOR + entryName; 562 if (!FileUtils.matchPattern(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); 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"); 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 FileTime fileTime = FileTime.fromMillis(FILE_TIME); 1078 zipEntry.setLastAccessTime(fileTime); 1079 zipEntry.setLastModifiedTime(fileTime); 1080 zipOut.putNextEntry(zipEntry); 1081 byte[] data = new byte[BUFFER_SIZE]; 1082 fileInputStream = new FileInputStream(srcFile); 1083 bufferedInputStream = new BufferedInputStream(fileInputStream); 1084 int count = bufferedInputStream.read(data); 1085 while (count > 0) { 1086 zipOut.write(data, 0, count); 1087 count = bufferedInputStream.read(data); 1088 } 1089 } catch (FileNotFoundException ignored) { 1090 LOG.error("Uncompress::compressFile file not found exception"); 1091 throw new BundleException("Compress file failed"); 1092 } catch (IOException exception) { 1093 LOG.error("Uncompress::compressFile io exception: " + exception.getMessage()); 1094 throw new BundleException("Compress file failed"); 1095 } finally { 1096 Utility.closeStream(fileInputStream); 1097 Utility.closeStream(bufferedInputStream); 1098 } 1099 } 1100 1101 /** 1102 * get CRC32 from file. 1103 * 1104 * @param file source file 1105 * @return CRC32 1106 * @throws BundleException FileNotFoundException|IOException. 1107 */ getCrcFromFile(File file)1108 private static CRC32 getCrcFromFile(File file) throws BundleException { 1109 FileInputStream fileInputStream = null; 1110 CRC32 crc = new CRC32(); 1111 try { 1112 fileInputStream = new FileInputStream(file); 1113 byte[] buffer = new byte[BUFFER_SIZE]; 1114 1115 int count = fileInputStream.read(buffer); 1116 while (count > 0) { 1117 crc.update(buffer, 0, count); 1118 count = fileInputStream.read(buffer); 1119 } 1120 } catch (FileNotFoundException ignored) { 1121 LOG.error("Uncompressor::getCrcFromFile file not found exception"); 1122 throw new BundleException("Get Crc from file failed"); 1123 } catch (IOException exception) { 1124 LOG.error("Uncompressor::getCrcFromFile io exception: " + exception.getMessage()); 1125 throw new BundleException("Get Crc from file failed"); 1126 } finally { 1127 Utility.closeStream(fileInputStream); 1128 } 1129 return crc; 1130 } 1131 1132 /** 1133 * delete file 1134 * 1135 * @param file the file to be deleted 1136 */ deleteFile(File file)1137 private static void deleteFile(File file) { 1138 if (file.exists()) { 1139 if (file.isDirectory()) { 1140 File[] files = file.listFiles(); 1141 for (int i = 0; i < files.length; i++) { 1142 deleteFile(files[i]); 1143 } 1144 } 1145 file.delete(); 1146 } 1147 } 1148 1149 /** 1150 * check 1151 * 1152 * @param result the result of parse app all mode 1153 * @return return the result of checkParseAllResult. 1154 */ checkParseAllResult(UncompressResult result)1155 private static UncompressResult checkParseAllResult(UncompressResult result) { 1156 UncompressResult errorResult = new UncompressResult(); 1157 errorResult.setResult(false); 1158 errorResult.setMessage("App package is invalid."); 1159 if (result == null || result.getPackInfos() == null || result.getProfileInfos() == null) { 1160 return errorResult; 1161 } 1162 1163 List<PackInfo> packInfos = result.getPackInfos(); 1164 List<ProfileInfo> profileInfos = result.getProfileInfos(); 1165 int packInfoSize = packInfos.size(); 1166 int profileInfoSize = profileInfos.size(); 1167 if (packInfoSize == 0 || profileInfoSize == 0 || packInfoSize != profileInfoSize) { 1168 LOG.error("Uncompress::checkParseAllResult error, hapNum is invalid in app"); 1169 return errorResult; 1170 } 1171 1172 for (int i = 0; i < packInfoSize; i++) { 1173 if (packInfos.get(i) == null || packInfos.get(i).name.isEmpty()) { 1174 return errorResult; 1175 } 1176 boolean isHave = false; 1177 for (int j = 0; j < profileInfoSize; j++) { 1178 if (profileInfos.get(j) == null || profileInfos.get(j).hapName.isEmpty()) { 1179 return errorResult; 1180 } 1181 if (comparePackAndProfile(packInfos.get(i), profileInfos.get(j))) { 1182 isHave = true; 1183 break; 1184 } 1185 } 1186 if (!isHave) { 1187 return errorResult; 1188 } 1189 } 1190 1191 return result; 1192 } 1193 1194 /** 1195 * get label and icon for application 1196 * 1197 * @param result the result of parse app all mode 1198 * @return return the result which contains icon and label 1199 */ obtainLabelAndIcon(UncompressResult result)1200 private static UncompressResult obtainLabelAndIcon(UncompressResult result) { 1201 List<ProfileInfo> profileInfos = result.getProfileInfos(); 1202 if (profileInfos.isEmpty()) { 1203 return result; 1204 } 1205 for (ProfileInfo profileInfo : profileInfos) { 1206 if (profileInfo == null) { 1207 continue; 1208 } 1209 HapInfo hapInfo = profileInfo.hapInfo; 1210 if (hapInfo == null) { 1211 continue; 1212 } 1213 Distro distro = hapInfo.distro; 1214 if (distro == null) { 1215 continue; 1216 } 1217 String moduleType = distro.moduleType; 1218 if (ENTRY_TYPE.equals(moduleType.toLowerCase(Locale.ENGLISH))) { 1219 return obtainInnerLabelAndIcon(result, hapInfo, distro); 1220 } 1221 } 1222 return result; 1223 } 1224 1225 /** 1226 * get label and icon for application 1227 * 1228 * @param result the result of parse app all mode 1229 * @param hapInfo hap info of entry hap 1230 * @return return the result which contains icon and label 1231 */ obtainInnerLabelAndIcon(UncompressResult result, HapInfo hapInfo, Distro distro)1232 private static UncompressResult obtainInnerLabelAndIcon(UncompressResult result, HapInfo hapInfo, Distro distro) { 1233 List<AbilityInfo> abilities = hapInfo.abilities; 1234 if ((abilities == null) || (abilities.isEmpty())) { 1235 result.setLabel(distro.moduleName); 1236 return result; 1237 } 1238 int size = 0; 1239 for (AbilityInfo info : abilities) { 1240 if (info == null) { 1241 size++; 1242 continue; 1243 } 1244 if ((info.skills == null) || (info.skills.isEmpty())) { 1245 continue; 1246 } 1247 for (SkillInfo skill : info.skills) { 1248 if (skill == null) { 1249 continue; 1250 } 1251 List<String> actions = skill.actions; 1252 List<String> entities = skill.entities; 1253 if ((!actions.isEmpty()) && (actions.contains(SYSTEM_ACTION) || actions.contains(SYSTEM_WANT_HOME))) { 1254 if ((!entities.isEmpty()) && (entities.contains(SYSTEM_ENTITY))) { 1255 result.setLabel(info.label); 1256 result.setIcon(info.icon); 1257 return result; 1258 } 1259 } 1260 } 1261 } 1262 if (size == abilities.size()) { 1263 result.setLabel(distro.moduleName); 1264 return result; 1265 } 1266 for (AbilityInfo info : abilities) { 1267 if (info != null) { 1268 result.setLabel(info.label); 1269 result.setIcon(info.icon); 1270 break; 1271 } 1272 } 1273 return result; 1274 } 1275 1276 isHarmonyProfile(String fileName)1277 private static boolean isHarmonyProfile(String fileName) { 1278 return HARMONY_PROFILE.equals(fileName); 1279 } 1280 isPackInfo(String fileName)1281 private static boolean isPackInfo(String fileName) { 1282 return PACK_INFO.equals(fileName); 1283 } 1284 getHapNameWithoutSuffix(String hapFileName)1285 private static String getHapNameWithoutSuffix(String hapFileName) { 1286 if (hapFileName == null || hapFileName.isEmpty() || hapFileName.lastIndexOf(".") == -1) { 1287 return ""; 1288 } 1289 return hapFileName.substring(0, hapFileName.lastIndexOf(".")); 1290 } 1291 unZipModuleHapFile(String srcPath)1292 private static HapZipInfo unZipModuleHapFile(String srcPath) 1293 throws BundleException, IOException { 1294 HapZipInfo hapZipInfo = new HapZipInfo(); 1295 ZipFile zipFile = null; 1296 try { 1297 File srcFile = new File(srcPath); 1298 zipFile = new ZipFile(srcFile); 1299 getProfileJson(zipFile, hapZipInfo.resourcemMap); 1300 hapZipInfo.setHarmonyProfileJsonStr(FileUtils.getFileStringFromZip(MODULE_JSON, zipFile)); 1301 hapZipInfo.setPackInfoJsonStr(FileUtils.getFileStringFromZip(PACK_INFO, zipFile)); 1302 hapZipInfo.setResDataBytes(getResourceDataFromHap(zipFile)); 1303 hapZipInfo.setHapFileName(getHapNameWithoutSuffix(srcFile.getName())); 1304 } finally { 1305 Utility.closeStream(zipFile); 1306 } 1307 return hapZipInfo; 1308 } 1309 1310 /** 1311 * uncompress from HapZipInfo 1312 * 1313 * @param hapZipInfo hap zip info 1314 * @return the parse moduleResult 1315 * @throws BundleException FileNotFoundException|IOException. 1316 */ uncompressModuleJsonInfo(HapZipInfo hapZipInfo, ModuleResult moduleResult)1317 private static void uncompressModuleJsonInfo(HapZipInfo hapZipInfo, ModuleResult moduleResult) 1318 throws BundleException { 1319 ModuleProfileInfo moduleProfileInfo = JsonUtil.parseModuleProfileInfo(hapZipInfo.getHarmonyProfileJsonStr(), 1320 hapZipInfo.getResDataBytes(), hapZipInfo.getPackInfoJsonStr(), hapZipInfo.getHapFileName(), 1321 hapZipInfo.resourcemMap); 1322 moduleProfileInfo.hapName = hapZipInfo.getHapFileName(); 1323 moduleResult.addModuleProfileInfo(moduleProfileInfo); 1324 moduleResult.moduleProfileStr.add(hapZipInfo.getHarmonyProfileJsonStr()); 1325 } 1326 1327 /** 1328 * uncompress from specified file name 1329 * 1330 * @param deviceType device type 1331 * @param srcPath source file path 1332 * @param fileName uncompress file name 1333 * @return the uncompress result 1334 * @throws BundleException FileNotFoundException|IOException. 1335 */ uncompressModule(String deviceType, String srcPath, String fileName)1336 private static ModuleResult uncompressModule(String deviceType, String srcPath, String fileName) 1337 throws BundleException { 1338 if (srcPath.isEmpty() || fileName.isEmpty()) { 1339 LOG.error("Uncompress::uncompressModule srcPath, fileName is empty!"); 1340 throw new BundleException("uncompressModule failed, srcPath or fileName is empty"); 1341 } 1342 ModuleResult moduleResult = new ModuleResult(); 1343 try { 1344 HapZipInfo hapZipInfo = unZipModuleHapFile(srcPath); 1345 uncompressModuleJsonInfo(hapZipInfo, moduleResult); 1346 if (moduleResult.packInfos.isEmpty() && !hapZipInfo.getPackInfoJsonStr().isEmpty()) { 1347 moduleResult.packInfos = JsonUtil.parsePackInfos(hapZipInfo.getPackInfoJsonStr()); 1348 } 1349 } catch (IOException exception) { 1350 moduleResult.setResult(false); 1351 LOG.error("Uncompress::uncompressModule parseMode is invalid!"); 1352 } 1353 return moduleResult; 1354 } 1355 1356 /** 1357 * uncompress module hap. 1358 * 1359 * @param deviceType indicates the device type of uncompress mode. 1360 * @param srcPath indicates the path type of hap. 1361 * @param fileName indicates json file name. 1362 * @return the uncompress result 1363 */ unCompressModuleHap(String deviceType, String srcPath, String fileName)1364 static UncompressResult unCompressModuleHap(String deviceType, String srcPath, String fileName) 1365 throws BundleException{ 1366 if (srcPath.isEmpty() || fileName.isEmpty()) { 1367 LOG.error("Uncompress::uncompress srcPath, fileName is empty!"); 1368 throw new BundleException("Uncompress failed, srcPath or fileName is empty"); 1369 } 1370 UncompressResult uncomperssResult = new UncompressResult(); 1371 ModuleResult moduleResult = new ModuleResult(); 1372 try { 1373 moduleResult = uncompressModule(deviceType, srcPath, fileName); 1374 ModuleAdaption moduleAdaption = new ModuleAdaption(); 1375 uncomperssResult = moduleAdaption.convertToUncompressResult(moduleResult); 1376 } catch (BundleException ignored) { 1377 LOG.error("Uncompress::uncompressHap Bundle exception"); 1378 uncomperssResult.setResult(false); 1379 uncomperssResult.setMessage("uncompressHap Bundle exception"); 1380 } 1381 return uncomperssResult; 1382 } 1383 /** 1384 * get all resource in profile. 1385 * 1386 * @param zipFile is the hap file 1387 * @return the parse resource result 1388 */ getProfileJson(ZipFile zipFile, HashMap<String, String> resourceMap)1389 static void getProfileJson(ZipFile zipFile, HashMap<String, String> resourceMap) throws BundleException { 1390 try { 1391 final Enumeration<? extends ZipEntry> entries = zipFile.entries(); 1392 while (entries.hasMoreElements()) { 1393 final ZipEntry entry = entries.nextElement(); 1394 if (entry.getName().contains(RESOURCE_PATH)) { 1395 String filePath = entry.getName(); 1396 String fileName = filePath.replaceAll(RESOURCE_PATH, ""); 1397 String fileContent = FileUtils.getFileStringFromZip(filePath, zipFile); 1398 resourceMap.put(fileName, fileContent); 1399 } 1400 } 1401 } catch (IOException e) { 1402 LOG.error("Uncompress::getProfileJson IOException"); 1403 throw new BundleException("Uncompress::getProfileJson failed"); 1404 } 1405 } 1406 1407 /** 1408 * uncompress module hap. 1409 * 1410 * @param deviceType indicates the deviceType of parse hap. 1411 * @param input the InputStream about the app package. 1412 * @param fileName the file name of json file. 1413 * @return the uncompress result 1414 */ uncompressModuleHapByInput(String deviceType, InputStream input, String fileName, String hapName)1415 static UncompressResult uncompressModuleHapByInput(String deviceType, 1416 InputStream input, String fileName, String hapName) { 1417 UncompressResult uncompressResult = new UncompressResult(); 1418 ModuleResult moduleResult = new ModuleResult(); 1419 try { 1420 moduleResult = uncompressModuleByInput(deviceType, input, MODULE_JSON, hapName); 1421 ModuleAdaption moduleAdaption = new ModuleAdaption(); 1422 uncompressResult = moduleAdaption.convertToUncompressResult(moduleResult); 1423 } catch (BundleException ignored) { 1424 LOG.error("Uncompress::uncompressHapByInput Bundle exception"); 1425 uncompressResult.setResult(false); 1426 uncompressResult.setMessage("uncompressHapByInput Bundle exception"); 1427 } 1428 return uncompressResult; 1429 } 1430 1431 /** 1432 * unzip module hap from zip file. 1433 * 1434 * @param input Indicates the InputStream about the package. 1435 * @return Return the uncomperss result of parseHap 1436 */ unZipModuleHapFileFromInputStream(InputStream input)1437 private static HapZipInfo unZipModuleHapFileFromInputStream(InputStream input) throws BundleException { 1438 BufferedInputStream bufIn = null; 1439 ZipInputStream zipIn = null; 1440 BufferedReader bufferedReader = null; 1441 HapZipInfo hapZipInfo = new HapZipInfo(); 1442 try { 1443 ZipEntry entry = null; 1444 bufIn = new BufferedInputStream(input); 1445 zipIn = new ZipInputStream(bufIn); 1446 while ((entry = zipIn.getNextEntry()) != null) { 1447 if (entry.getName().toLowerCase().endsWith(RESOURCE_INDEX)) { 1448 hapZipInfo.setResDataBytes(getByte(zipIn)); 1449 continue; 1450 } 1451 if (isPackInfo(entry.getName())) { 1452 bufferedReader = new BufferedReader(new InputStreamReader(zipIn)); 1453 hapZipInfo.setPackInfoJsonStr(readStringFromInputStream(zipIn, bufferedReader)); 1454 continue; 1455 } 1456 if (MODULE_JSON.equals(entry.getName())) { 1457 bufferedReader = new BufferedReader(new InputStreamReader(zipIn)); 1458 hapZipInfo.setHarmonyProfileJsonStr(readStringFromInputStream(zipIn, bufferedReader)); 1459 } 1460 if (entry.getName().contains(RESOURCE_PATH)) { 1461 bufferedReader = new BufferedReader(new InputStreamReader(zipIn)); 1462 String filePath = entry.getName(); 1463 String fileName = filePath.replaceAll(RESOURCE_PATH, ""); 1464 String fileContent = readStringFromInputStream(zipIn, bufferedReader); 1465 hapZipInfo.pushResourceMap(fileName, fileContent); 1466 } 1467 } 1468 } catch (BundleException | IOException e) { 1469 LOG.error("unZipModuleHapFileFromInputStream failed!"); 1470 throw new BundleException("unZipModuleHapFileFromInputStream failed!"); 1471 } finally { 1472 Utility.closeStream(bufferedReader); 1473 Utility.closeStream(bufIn); 1474 Utility.closeStream(zipIn); 1475 } 1476 return hapZipInfo; 1477 } 1478 1479 /** 1480 * Parse the hap type. 1481 * 1482 * @param hapPath Indicates the hap path. 1483 * @param compressResult Indicates the result of parse hap. 1484 * @return Return the type result of isModuleHap 1485 */ isModuleHap(String hapPath, UncompressResult compressResult)1486 public static boolean isModuleHap(String hapPath, UncompressResult compressResult) { 1487 ZipFile zipFile = null; 1488 try { 1489 zipFile = new ZipFile(new File(hapPath)); 1490 final Enumeration<? extends ZipEntry> entries = zipFile.entries(); 1491 while (entries.hasMoreElements()) { 1492 final ZipEntry entry = entries.nextElement(); 1493 if (MODULE_JSON.equals(entry.getName())) { 1494 return true; 1495 } 1496 } 1497 } catch (FileNotFoundException ignored) { 1498 LOG.error("Uncompress::isModuleHap file not found exception"); 1499 compressResult.setResult(false); 1500 compressResult.setMessage("judge is module failed"); 1501 } catch (IOException exception) { 1502 LOG.error("Uncompress::isModuleHap io exception: " + exception.getMessage()); 1503 compressResult.setResult(false); 1504 compressResult.setMessage("judge is module failed"); 1505 } finally { 1506 Utility.closeStream(zipFile); 1507 } 1508 return false; 1509 } 1510 1511 /** 1512 * Parse the hap type. 1513 * 1514 * @param input Indicates the hap FileInputStream. 1515 * @return Return the type result of isModuleHap. 1516 */ isModuleInput(InputStream input)1517 public static boolean isModuleInput(InputStream input) throws BundleException { 1518 BufferedInputStream bufIn = null; 1519 ZipInputStream zipIn = null; 1520 BufferedReader bufferedReader = null; 1521 try { 1522 ZipEntry entry = null; 1523 bufIn = new BufferedInputStream(input); 1524 zipIn = new ZipInputStream(bufIn); 1525 while((entry = zipIn.getNextEntry()) != null) { 1526 if (entry.getName().toLowerCase().endsWith(MODULE_JSON)) { 1527 return true; 1528 } 1529 } 1530 } catch (IOException ignored) { 1531 LOG.error("Uncompress::isModuleHap judge failed!"); 1532 throw new BundleException("Uncompress::isModuleHap judge failed!"); 1533 } finally { 1534 Utility.closeStream(bufferedReader); 1535 Utility.closeStream(bufIn); 1536 Utility.closeStream(zipIn); 1537 } 1538 return false; 1539 } 1540 1541 /** 1542 * create file output stream from InputStream . 1543 * 1544 * @param stream Indicates the input stream of hap. 1545 * @param file Indicates the temp file to save input stream. 1546 */ writeToTempFile(InputStream stream, File file)1547 static void writeToTempFile(InputStream stream, File file) throws BundleException { 1548 FileOutputStream fileOutputStream = null; 1549 try { 1550 if (file == null) { 1551 LOG.error("file not exist!"); 1552 } 1553 fileOutputStream = new FileOutputStream(file); 1554 int bytesRead = 0; 1555 byte[] buffer = new byte[1024]; 1556 while ((bytesRead = stream.read(buffer)) != -1) { 1557 fileOutputStream.write(buffer, 0, bytesRead); 1558 } 1559 } catch (IOException e) { 1560 LOG.error("writeToTempFile failed!"); 1561 throw new BundleException("writeToTempFile failed!"); 1562 } finally { 1563 Utility.closeStream(fileOutputStream); 1564 } 1565 } 1566 1567 /** 1568 * copy rpcid.sc file. 1569 * 1570 * @param srcFile Indicates the path of hap. 1571 * @param rpcidPath Indicates the output path of rpcid.sc file. 1572 */ getRpcidFromHap(String srcFile, String rpcidPath)1573 static void getRpcidFromHap(String srcFile, String rpcidPath) throws BundleException { 1574 ZipFile zipFile = null; 1575 InputStream inputStream = null; 1576 FileOutputStream outputStream = null; 1577 try { 1578 zipFile = new ZipFile(srcFile); 1579 String filePath = null; 1580 final Enumeration<? extends ZipEntry> entries = zipFile.entries(); 1581 while (entries.hasMoreElements()) { 1582 final ZipEntry entry = entries.nextElement(); 1583 if (RPCID_SC.equals(entry.getName())) { 1584 filePath = entry.getName(); 1585 break; 1586 } 1587 } 1588 if (filePath != null) { 1589 File rpcidFile = new File(rpcidPath, RPCID_SC); 1590 if (rpcidFile.getParentFile() != null && !rpcidFile.getParentFile().exists()) { 1591 rpcidFile.getParentFile().mkdirs(); 1592 } 1593 ZipEntry rpcidEntry = zipFile.getEntry(filePath); 1594 inputStream = zipFile.getInputStream(rpcidEntry); 1595 byte[] buffer = new byte[1024]; 1596 int noBytes = 0; 1597 outputStream = new FileOutputStream(rpcidFile); 1598 while((noBytes = inputStream.read(buffer)) != -1) { 1599 outputStream.write(buffer, 0, noBytes); 1600 } 1601 } else { 1602 LOG.error("Uncompress::getRpcidFromHap hap has no rpcid.sc file"); 1603 throw new BundleException("Uncompress::getRpcidFromHap hap has no rpcid.sc file"); 1604 } 1605 } catch (IOException e) { 1606 LOG.error("Uncompress::getRpcidFromHap IOException " + e.getMessage()); 1607 throw new BundleException("Uncompress::getRpcidFromHap failed"); 1608 } finally { 1609 Utility.closeStream(zipFile); 1610 Utility.closeStream(inputStream); 1611 Utility.closeStream(outputStream); 1612 } 1613 } 1614 1615 /** 1616 * parse resource.index file. 1617 * 1618 * @param srcPath Indicates the path of hap. 1619 */ getResourceFromHap(String srcPath)1620 static List<ResourceIndexResult> getResourceFromHap(String srcPath) throws BundleException, IOException { 1621 ZipFile zipFile = null; 1622 try { 1623 File srcFile = new File(srcPath); 1624 zipFile = new ZipFile(srcFile); 1625 byte[] data = getResourceDataFromHap(zipFile); 1626 return ResourcesParser.getAllDataItem(data); 1627 } finally { 1628 Utility.closeStream(zipFile); 1629 } 1630 } 1631 1632 /** 1633 * uncompress appqf file. 1634 * 1635 * @param utility is the common args for input. 1636 * @throws BundleException if uncompress failed. 1637 */ uncompressAPPQFFile(Utility utility)1638 private static void uncompressAPPQFFile(Utility utility) throws BundleException { 1639 ZipFile zipFile = null; 1640 try { 1641 zipFile = new ZipFile(new File(utility.getAPPQFPath())); 1642 int entriesNum = 0; 1643 for (Enumeration<? extends ZipEntry> entries = zipFile.entries(); entries.hasMoreElements();) { 1644 entriesNum++; 1645 ZipEntry entry = entries.nextElement(); 1646 if (entry == null) { 1647 continue; 1648 } 1649 String filePath = utility.getOutPath() + File.separator + entry.getName(); 1650 if (!FileUtils.matchPattern(filePath)) { 1651 LOG.error("uncompressAPPQFFile: Input invalid file" + filePath); 1652 throw new BundleException("uncompressAPPQFFile: Input invalid file" + filePath); 1653 } 1654 File destFile = new File(filePath); 1655 if (destFile != null && destFile.getParentFile() != null && !destFile.getParentFile().exists()) { 1656 destFile.getParentFile().mkdirs(); 1657 } 1658 dataTransfer(zipFile, entry, destFile); 1659 } 1660 } catch (FileNotFoundException ignored) { 1661 LOG.error("Uncompress::uncompressAPPQFFile file not found exception"); 1662 throw new BundleException("Uncompress::uncompressAPPQFFile file not found"); 1663 } catch (IOException exception) { 1664 LOG.error("Uncompress::uncompressAPPQFFile io exception"); 1665 throw new BundleException("Uncompress::uncompressAPPQFFile io exception"); 1666 } finally { 1667 Utility.closeStream(zipFile); 1668 } 1669 } 1670 1671 /** 1672 * parse appqf file, . 1673 * 1674 * @param appqfPath is the path of appqf file. 1675 * @throws BundleException if uncompress failed. 1676 * @throws IOException if IOException happened. 1677 */ parseAPPQFFile(String appqfPath)1678 public static List<HQFInfo> parseAPPQFFile(String appqfPath) throws BundleException { 1679 List<String> patchList = new ArrayList<>(); 1680 ZipFile zipFile = null; 1681 InputStream stream = null; 1682 ZipInputStream zipInputStream = null; 1683 try { 1684 zipFile = new ZipFile(appqfPath); 1685 Enumeration<? extends ZipEntry> entries = zipFile.entries(); 1686 while (entries.hasMoreElements()) { 1687 ZipEntry appqfEntry = entries.nextElement(); 1688 stream = zipFile.getInputStream(appqfEntry); 1689 if (!appqfEntry.getName().endsWith(HQF_SUFFIX)) { 1690 continue; 1691 } 1692 zipInputStream = new ZipInputStream(stream); 1693 String patchJson = readPatchJson(zipInputStream); 1694 if (patchJson == null) { 1695 continue; 1696 } 1697 patchList.add(patchJson); 1698 } 1699 } catch (IOException e) { 1700 LOG.error("parseAPPQFFile failed!"); 1701 throw new BundleException("parseAPPQFFile failed!"); 1702 } finally { 1703 Utility.closeStream(zipFile); 1704 Utility.closeStream(stream); 1705 Utility.closeStream(zipInputStream); 1706 } 1707 return parsePatchJson(patchList); 1708 } 1709 readPatchJson(ZipInputStream zipInputStream)1710 private static String readPatchJson(ZipInputStream zipInputStream) throws BundleException { 1711 String patchJson = null; 1712 ZipEntry hqfEntry; 1713 try { 1714 while ((hqfEntry = zipInputStream.getNextEntry()) != null) { 1715 if (!PATCH_JSON.equals(hqfEntry.getName())) { 1716 continue; 1717 } 1718 patchJson = new BufferedReader(new InputStreamReader(zipInputStream, 1719 StandardCharsets.UTF_8)).lines().parallel() 1720 .collect(Collectors.joining(System.lineSeparator())); 1721 } 1722 } catch (IOException e) { 1723 LOG.error("readPatchJson failed!"); 1724 throw new BundleException("readPatchJson failed!"); 1725 } 1726 return patchJson; 1727 } 1728 parsePatchJson(List<String> patchList)1729 private static List<HQFInfo> parsePatchJson(List<String> patchList) throws BundleException { 1730 List<HQFInfo> hqfInfoList = new ArrayList<>(); 1731 for (String patchJson : patchList) { 1732 hqfInfoList.add(JsonUtil.parsePatch(patchJson)); 1733 } 1734 return hqfInfoList; 1735 } 1736 comparePackAndProfile(PackInfo packInfo, ProfileInfo profileInfo)1737 private static boolean comparePackAndProfile(PackInfo packInfo, ProfileInfo profileInfo) { 1738 if (profileInfo.hapName.replace(HAP_SUFFIXI, "").equals(packInfo.name.replace(HAP_SUFFIXI, ""))) { 1739 return true; 1740 } 1741 if (profileInfo.hapName.replace(HSP_SUFFIX, "").equals(packInfo.name.replace(HSP_SUFFIX, ""))) { 1742 return true; 1743 } 1744 return false; 1745 } 1746 } 1747