merge_ad_pkg.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. # -*- coding:utf-8 -*-
  2. import sys
  3. import os
  4. import xml.etree.ElementTree as ET
  5. from V1 import Contants, Exec_Cmd_Utils, HttpUtils, Replace_GameRes_Utils, PrintLog, Json_Util, File, Replace, \
  6. apk_utils, Icon_Util
  7. from V1.PrintLog import printlog
  8. import random
  9. import shutil
  10. import yaml
  11. import json
  12. import traceback
  13. import time
  14. SUFFIX_BAT = ""
  15. DIR_SPLIT = "/"
  16. keystorepath = "/opt/packing_tool/keystore/yyrh.jks"
  17. storepass = "yyrh123456"
  18. keypass = "yyrh123456"
  19. alias = "yyrh"
  20. def startMerge(config_json_path):
  21. global ad_code_list, sp_code, apk_decompile_tmp_dir
  22. isSuccess = True
  23. errorMsg = "切包失败,请联系开发人员"
  24. time_start = time.time()
  25. try:
  26. sp_code = Json_Util.ReadJson(config_json_path, "sp_code")
  27. PrintLog.LOGFILE = "%s/%s.txt" % (Contants.SDK_LOG, sp_code)
  28. if os.path.exists(PrintLog.LOGFILE):
  29. os.remove(PrintLog.LOGFILE)
  30. printlog("[LOGFILE] : %s" % PrintLog.LOGFILE)
  31. printlog("[sp_code] : %s" % sp_code)
  32. origin_apk_full_path = Json_Util.ReadJson(config_json_path, "sub_apk_path")
  33. printlog("[origin_apk_full_path] : %s" % origin_apk_full_path)
  34. origin_apk_dir = os.path.dirname(origin_apk_full_path)
  35. origin_apk_full_name = os.path.basename(origin_apk_full_path)
  36. printlog("[origin_apk_dir] %s" % origin_apk_dir)
  37. randomNumber = getRamdomNumber(6)
  38. origin_apk_name = os.path.splitext(origin_apk_full_name)[0]
  39. apk_decompile_tmp_dir = origin_apk_dir + DIR_SPLIT + randomNumber + DIR_SPLIT + origin_apk_name
  40. ad_sdk_type = Json_Util.ReadJson(config_json_path, "ad_sdk_type")
  41. printlog("[ad_sdk_type] : %s" % ad_sdk_type)
  42. ad_allow_pt = Json_Util.ReadJson(config_json_path, "ad_allow_pt")
  43. printlog("[ad_allow_pt] : %s" % ad_allow_pt)
  44. ad_code_list = json.dumps(Json_Util.ReadJson(config_json_path, "ad_code_list"))
  45. printlog("[ad_code_list] : %s" % ad_code_list)
  46. sdk_code = Json_Util.ReadJson(config_json_path, "sdk_code")
  47. printlog("[sdk_code] : %s" % sdk_code)
  48. channel_map_id = Json_Util.ReadJson(config_json_path, "channel_map_id")
  49. printlog("[channel_map_id] : %s" % channel_map_id)
  50. # 包名
  51. package_name = Json_Util.ReadJson(config_json_path, "package_name") # sys.argv[3]
  52. printlog("[package_name] : %s" % package_name)
  53. # 版本号
  54. version = Json_Util.ReadJson(config_json_path, "version")
  55. vCode = Json_Util.ReadJson(config_json_path, "v_code")
  56. # targetSdkVersion
  57. targetSdkVersion = Json_Util.ReadJson(config_json_path, "targetSdkVersion")
  58. # icon路径
  59. icon_path = Json_Util.ReadJson(config_json_path, "icon_path")
  60. printlog("[icon_path]: %s" % icon_path)
  61. unsignedApkPath = "%s_unsigned.apk" % apk_decompile_tmp_dir
  62. printlog("unsignedApkPath: %s" % unsignedApkPath)
  63. signedApkPath = "%s_signed.apk" % apk_decompile_tmp_dir
  64. printlog("signedApkPath: %s" % signedApkPath)
  65. zipalignApkPath = "%s_zipaligned.apk" % apk_decompile_tmp_dir
  66. printlog("zipalignApkPath: %s" % zipalignApkPath)
  67. HttpUtils.notify_sp_cut_state(sp_code, "10", "正在反编译文件", ad_code_list)
  68. printlog("----- begin decompile -----")
  69. ret = decompile(origin_apk_full_path, apk_decompile_tmp_dir)
  70. if ret == 1:
  71. errorMsg = "找不到游戏母包,请检查"
  72. isSuccess = False
  73. printlog(errorMsg)
  74. HttpUtils.notify_sp_cut_state(sp_code, "99", errorMsg, ad_code_list)
  75. return
  76. printlog("----- begin replace params -----")
  77. temp_xml_path = apk_decompile_tmp_dir + DIR_SPLIT + "AndroidManifest.xml"
  78. printlog("temp_xml_path %s" % temp_xml_path)
  79. HttpUtils.notify_sp_cut_state(sp_code, "30", "正在修改SP_CODE", ad_code_list)
  80. if ad_allow_pt != 0:
  81. add_andriod_node(temp_xml_path, "yyrh_sp_code", sp_code)
  82. HttpUtils.notify_sp_cut_state(sp_code, "40", "正在修改合并渠道", ad_code_list)
  83. if ad_sdk_type == 2:
  84. sdk_name = Json_Util.ReadJson(config_json_path, "sdk_code")
  85. printlog("[sdk_name] : %s" % sdk_name)
  86. sdk_root_dir = apk_utils.getCutAdSdkRootHome()
  87. mergeManifest(sdk_root_dir + DIR_SPLIT + sdk_name + DIR_SPLIT + sdk_name + "_sdk_config.xml",
  88. temp_xml_path)
  89. mergeResources(sdk_root_dir + DIR_SPLIT + sdk_name + DIR_SPLIT + sdk_name, apk_decompile_tmp_dir)
  90. sdkParam = Json_Util.ReadJson(config_json_path, "sdk_param_conf")
  91. printlog("channel sdk_param_conf: %s" % str(sdkParam))
  92. # 替换Androidmanifest.xml中的 package_name值为包名
  93. Replace.replaceAM_package_name(temp_xml_path)
  94. if sdkParam != None and sdkParam != "":
  95. keys = Json_Util.getJsonKeys(sdkParam)
  96. for key in keys:
  97. printlog(key)
  98. # 替换AndroidManifest.xml中的meta-data字段
  99. Replace.replaceAM_Meta_data(temp_xml_path, key,
  100. sdkParam[key])
  101. # 替换assets/YyrhAdParam.cnf中的关键字
  102. Replace.replaceAssets_Param(
  103. apk_decompile_tmp_dir + DIR_SPLIT + "assets" + DIR_SPLIT + "YyrhAdParam.cnf", key,
  104. sdkParam[key])
  105. # 特殊渠道需要特殊处理
  106. # Replace.special_replace(sdk_name, apk_decompile_tmp_dir, DIR_SPLIT, key, sdkParam[key])
  107. pass
  108. # 修改包Apk文件名
  109. # 修改包名
  110. if package_name:
  111. oldPkgName = getOldPkgName(temp_xml_path)
  112. origin_apk_name = origin_apk_name.replace(oldPkgName, package_name)
  113. modifyPkgName(temp_xml_path, package_name)
  114. pass
  115. # 替换Icon
  116. printlog("----- begin replace resource -----")
  117. HttpUtils.notify_sp_cut_state(sp_code, "50", "正在替换资源", ad_code_list)
  118. if icon_path:
  119. ret = Icon_Util.replaceIcon(icon_path, apk_decompile_tmp_dir)
  120. if not ret:
  121. errorMsg = "找不到icon,请检查"
  122. printlog(errorMsg)
  123. HttpUtils.notify_cut_state(sp_code, "99", errorMsg)
  124. # 替换启动页
  125. splash_path = Json_Util.ReadJson(config_json_path, "splash_path")
  126. printlog("splash_path:%s" % splash_path)
  127. if splash_path is not None:
  128. if os.path.exists(splash_path):
  129. shutil.copy(splash_path, "%s/assets/yyrh_start_image.jpg" % apk_decompile_tmp_dir)
  130. else:
  131. errorMsg = "找不到闪屏文件,请检查"
  132. isSuccess = False
  133. printlog(errorMsg)
  134. HttpUtils.notify_sp_cut_state(sp_code, "99", errorMsg, ad_code_list)
  135. return
  136. # 获取游戏名,版本号,版本名,targetSdkVersion,屏幕方向关键字
  137. gameParam = Json_Util.ReadJson(config_json_path, "meta_config_value")
  138. printlog("gameParam:%s" % str(gameParam))
  139. if gameParam:
  140. keys = Json_Util.getJsonKeys(gameParam)
  141. for key in keys:
  142. if key == "APP_NAME":
  143. Replace.replaceString_Appname(apk_decompile_tmp_dir, key, gameParam[key])
  144. elif key == "version":
  145. version = gameParam[key]
  146. elif key == "v_code":
  147. vCode = gameParam[key]
  148. elif key == "targetSdkVersion":
  149. targetSdkVersion = gameParam[key]
  150. # 替换方向
  151. elif key == "SDK_ORIENTATION":
  152. replaceOrientation = '/bin/sed -i "1,\\$s/sdk_orientation/%s/g" %s' % (
  153. gameParam[key], temp_xml_path)
  154. printlog("replaceOrientation: %s" % replaceOrientation)
  155. os.system(replaceOrientation)
  156. Replace.replaceAssets_Param(
  157. apk_decompile_tmp_dir + DIR_SPLIT + "assets" + DIR_SPLIT + "YyrhParam.cnf", "SDK_ORIENTATION",
  158. gameParam[key])
  159. pass
  160. # 修改版本号 targetSdkVersion
  161. printlog("version: %s vCode : %s" % (version, vCode))
  162. printlog("targetSdkVersion: %s" % targetSdkVersion)
  163. yml = "%s/apktool.yml" % apk_decompile_tmp_dir
  164. if version != None and version != "":
  165. Replace.replaceAM_VersionName(yml, version)
  166. if vCode != None and vCode != "":
  167. Replace.replaceAM_VersionCode(yml, vCode)
  168. if targetSdkVersion != None and targetSdkVersion != "":
  169. Replace.replaceYml_targetSdkVersion(yml, targetSdkVersion)
  170. HttpUtils.notify_sp_cut_state(sp_code, "70", "正在替换游戏资源", ad_code_list)
  171. # 替换游戏资源
  172. resourcepaths = Json_Util.ReadJson(config_json_path, "game_resource_replace_path")
  173. printlog(str(resourcepaths))
  174. resourceconfigs = Json_Util.ReadJson(config_json_path, "game_resource_config")
  175. if resourcepaths is not None:
  176. keys = Json_Util.getJsonKeys(resourcepaths)
  177. for key in keys:
  178. path = resourcepaths[key]
  179. printlog(path)
  180. if not os.path.exists(path) and path != "":
  181. errorMsg = "游戏资源不存在:%s" % path
  182. printlog(errorMsg)
  183. isSuccess = False
  184. HttpUtils.notify_sp_cut_state(sp_code, "99", errorMsg, ad_code_list)
  185. return
  186. printlog("replace game resource.")
  187. Replace_GameRes_Utils.replaceAdGameResource(apk_decompile_tmp_dir, resourcepaths, resourceconfigs)
  188. printlog("----- begin recompile apk -----")
  189. HttpUtils.notify_sp_cut_state(sp_code, "80", "正在回编译APK", ad_code_list)
  190. recompile(apk_decompile_tmp_dir, unsignedApkPath)
  191. printlog("unsignedApkPath: %s" % unsignedApkPath)
  192. printlog("----- begin resign apk -----")
  193. HttpUtils.notify_sp_cut_state(sp_code, "90", "正在重签名,对齐APK", ad_code_list)
  194. resignApk(unsignedApkPath, keystorepath, storepass, alias, keypass, signedApkPath)
  195. printlog("signedApkPath %s" % signedApkPath)
  196. printlog("----- begin zipalign apk -----")
  197. zipalignApk(signedApkPath, zipalignApkPath)
  198. printlog("zipalignApkPath %s" % zipalignApkPath)
  199. dst_dir = "%s%s" % (apk_utils.getSpOutPutDir(), DIR_SPLIT)
  200. apkDstPath = "%s%s_%s.apk" % (dst_dir, origin_apk_name, sp_code)
  201. printlog("origin_apk_name %s" % origin_apk_name)
  202. if ad_allow_pt == 0 and ad_sdk_type == 2:
  203. apkDstPath = "%s%s_%s_%s.apk" % (dst_dir, origin_apk_name, sdk_code, channel_map_id)
  204. if ad_allow_pt == 0 and ad_sdk_type == 1:
  205. apkDstPath = "%s%s_%s_%s.apk" % (dst_dir, origin_apk_name, sdk_code, channel_map_id)
  206. if not os.path.exists(dst_dir):
  207. os.makedirs(dst_dir)
  208. printlog("apkDstPath %s" % apkDstPath)
  209. shutil.copyfile(zipalignApkPath, apkDstPath)
  210. time_end = time.time()
  211. time_c = time_end - time_start
  212. printlog("切包总用时:%s秒" % time_c)
  213. HttpUtils.notify_sp_cut_state(sp_code, "100", "切包成功(点击复制链接)", ad_code_list)
  214. except Exception as err:
  215. HttpUtils.notify_sp_cut_state(sp_code, "99", errorMsg, ad_code_list)
  216. printlog("cut error occur:%s" % err)
  217. isSuccess = False
  218. printlog(traceback.format_exc())
  219. finally:
  220. if apk_decompile_tmp_dir:
  221. File.safeFileDelete(os.path.dirname(apk_decompile_tmp_dir))
  222. return isSuccess
  223. def decompile(apkPath, desPath):
  224. printlog("start to apkPath %s" % apkPath)
  225. global SUFFIX_BAT
  226. if os.path.exists(apkPath) == False:
  227. printlog("no such apk:%s" % apkPath)
  228. return 1
  229. home = apk_utils.getComplieToolsHome()
  230. decompileCmd = "%s/apktool%s d -f %s -o %s" % (home, SUFFIX_BAT, apkPath, desPath)
  231. printlog("decompileCmd:%s" % decompileCmd)
  232. ret = os.system(decompileCmd)
  233. printlog("finished decompiling -------------------------")
  234. return ret
  235. # recompile fileset to apk
  236. def recompile(apkPath, outputApkPath):
  237. global SUFFIX_BAT
  238. printlog("------------------------------ start to recompile ------------------------------ ")
  239. global SUFFIX_BAT
  240. recompileCmd = "%s/apktool%s -q b %s -o %s" % (apk_utils.getComplieToolsHome(), SUFFIX_BAT, apkPath, outputApkPath)
  241. status, output = Exec_Cmd_Utils.exeCommonCmd(recompileCmd)
  242. printlog(output)
  243. if status != 0:
  244. return 1
  245. printlog("------------------------------ finished recompiling ------------------------------ ")
  246. return 0
  247. def zipalignApk(unZipalignApk, outputPath=""):
  248. printlog("start to zipalign apk ----------------------------")
  249. if outputPath == "":
  250. point = unZipalignApk.rfind(".")
  251. outputPath = unZipalignApk[0:point] + "_zipaligned" + unZipalignApk[point:]
  252. printlog("outputPath:%s" % outputPath)
  253. zipalignCmd = "%s/zipalign -f 4 %s %s" % (apk_utils.getSdkToolsPath(), unZipalignApk, outputPath)
  254. printlog("zipalignCmd:%s" % zipalignCmd)
  255. status, output = Exec_Cmd_Utils.exeCommonCmd(zipalignCmd)
  256. printlog(output)
  257. if status != 0:
  258. return 1
  259. printlog("finished zipaligning apk -----------------------------")
  260. return 0
  261. def add_andriod_node(xmlpath, key, value):
  262. global child
  263. ET.register_namespace('android', 'http://schemas.android.com/apk/res/android')
  264. tree = ET.parse(xmlpath)
  265. root = tree.getroot()
  266. node = ET.Element("meta-data")
  267. node.set("android:name", key)
  268. node.set("android:value", value)
  269. node.tail = "\n\t"
  270. for i in root.iter("application"):
  271. for child in i:
  272. pass
  273. child.tail = '\n\t\t'
  274. for a in root.iter("application"):
  275. a.append(node)
  276. break
  277. tree.write(xmlpath, encoding="utf-8", xml_declaration=True)
  278. def getRamdomNumber(size):
  279. str = ""
  280. for i in range(size):
  281. ch = chr(random.randrange(ord('0'), ord('9') + 1))
  282. str += ch
  283. return str
  284. def resignApk(unsignedApkPath, keystorepath, storepass, alias, keypass, outputPath=""):
  285. printlog("start to resign apk -----------------------")
  286. if outputPath == "":
  287. point = unsignedApkPath.rfind(".")
  288. outputPath = unsignedApkPath[0:point] + "_signed" + unsignedApkPath[point:]
  289. printlog("signedName:%s" % outputPath)
  290. # 获取签名算法
  291. getKeystoreAlgorithmShell = "%s/keytool -list -v -keystore %s -alias %s -storepass %s | /bin/sed -n \"13p\" | /usr/bin/awk -F ': ' '{print $2}'" % (
  292. apk_utils.getJavaBinPath(), keystorepath, alias, storepass)
  293. printlog("getKeystoreAlgorithmShell: %s" % getKeystoreAlgorithmShell)
  294. ret, algorithm = Exec_Cmd_Utils.exeCommonCmd(getKeystoreAlgorithmShell)
  295. algorithmMethod = algorithm.strip()
  296. printlog("algorithmMethod: %s" % algorithmMethod)
  297. resignCmd = "%s/jarsigner -sigalg %s -digestalg SHA1 -storepass %s -keypass %s -keystore %s -signedjar %s %s %s" % (
  298. apk_utils.getJavaBinPath(), algorithmMethod, storepass, keypass, keystorepath, outputPath, unsignedApkPath,
  299. alias)
  300. printlog("resignCmd:%s" % resignCmd)
  301. status, output = Exec_Cmd_Utils.exeCommonCmd(resignCmd)
  302. printlog(output)
  303. if status != 0:
  304. return 1
  305. printlog("finished resigning apk --------------------------")
  306. return 0
  307. def modifyPkgName(temp_xml_path, pkgName):
  308. # 修改包名
  309. manifestRoot = ET.parse(temp_xml_path).getroot()
  310. if manifestRoot == None:
  311. return 1
  312. if pkgName == "":
  313. pkgName = manifestRoot.attrib["package"]
  314. printlog("get pkg name:%s" % pkgName)
  315. else:
  316. oldPkgName = manifestRoot.attrib["package"]
  317. content = open(temp_xml_path, "r").read()
  318. content = content.replace(oldPkgName, pkgName)
  319. open(temp_xml_path, "w").write(content)
  320. printlog("old pkg name:%s" % oldPkgName)
  321. printlog("new pkg name:%s" % pkgName)
  322. def getOldPkgName(temp_xml_path):
  323. # 修改包名
  324. manifestRoot = ET.parse(temp_xml_path).getroot()
  325. if manifestRoot is None:
  326. return ""
  327. else:
  328. oldPkgName = manifestRoot.attrib["package"]
  329. return oldPkgName
  330. def mergeLibs(sdkPath, apkPath):
  331. printlog("start to merge lib --------------------------------")
  332. apkLib = "%s/lib" % apkPath
  333. sdkLib = "%s/lib" % sdkPath
  334. ret = 0
  335. if not os.path.exists(apkLib) and os.path.exists(sdkLib):
  336. shutil.copytree(sdkLib, apkLib)
  337. printlog("finished merging lib --------------------------------")
  338. return ret
  339. apkFiles = os.listdir(apkLib)
  340. sdkFiles = os.listdir(sdkLib)
  341. for cpFile in sdkFiles:
  342. if os.path.isfile(cpFile) == False and cpFile not in apkFiles:
  343. continue
  344. ret = ret | File.copyFiles("%s/lib/%s" % (sdkPath, cpFile), "%s/lib/%s" % (apkPath, cpFile))
  345. printlog("finished merging lib --------------------------------")
  346. return ret
  347. # sdk resources + apk resources
  348. def mergeResources(sdkPath, apkPath):
  349. printlog("mergeResources apkPath : %s" % apkPath)
  350. printlog("start to merge resources ---------------------------")
  351. ret = 0
  352. # merge res
  353. printlog("start to merge copyFiles ---------------------------")
  354. ret = ret | File.copyFiles("%s/res" % sdkPath, "%s/res" % apkPath)
  355. printlog("start to merge mergeLibs ---------------------------")
  356. # copy lib and assets
  357. ret = ret | mergeLibs(sdkPath, apkPath)
  358. printlog("start to merge assets ---------------------------")
  359. ret = ret | File.copyFiles("%s/assets" % sdkPath, "%s/assets" % apkPath)
  360. printlog("start to merge smali ---------------------------")
  361. ret = ret | File.mergeDir("%s/smali" % sdkPath, "%s/smali" % apkPath)
  362. printlog("start to merge unknown ---------------------------")
  363. ret = ret | File.mergeDir("%s/unknown" % sdkPath, "%s/unknown" % apkPath)
  364. # 暂时的方案是用sdk的apktool.yml覆盖原包apktool.yml 后期需要做apktool.yml合并
  365. if os.path.exists("%s/apktool.yml" % sdkPath):
  366. printlog("start to merge apktool.yml ---------------------------")
  367. mergeYml("%s/apktool.yml" % sdkPath, "%s/apktool.yml" % apkPath)
  368. # shutil.copy("%s/apktool.yml"%sdkPath, "%s/apktool.yml"%apkPath)
  369. # 修改微信支付
  370. # ret = ret | File.copyFiles("%s/smali"%sdkPath,"%s/smali"%apkPath)
  371. printlog("finished merging resources ---------------------------")
  372. return ret
  373. def mergeManifest(sdkConfigPath, temp_xml_path):
  374. printlog("start to merge AndroidManifest.xml -------------------------")
  375. ret = 0
  376. ret = ret | File.mergeManifest(temp_xml_path, sdkConfigPath)
  377. # 根据配置修改游戏名,包名等
  378. printlog("finished merging AndroidManifest.xml -------------------------")
  379. return ret
  380. def compileResources(apkPath, tempDir, pkgName=""):
  381. printlog("[start to compile resources] -----------------------------------")
  382. global SUFFIX_EXE
  383. global SUFFIX_BAT
  384. if File.copyFiles("%s/res" % apkPath, "%s/res" % tempDir) != 0:
  385. printlog("no such files")
  386. return 1
  387. if not os.path.exists("%s/gen" % tempDir):
  388. os.mkdir("%s/gen" % tempDir)
  389. # 修改包名
  390. manifestRoot = ET.parse("%s/AndroidManifest.xml" % apkPath).getroot()
  391. if manifestRoot is None:
  392. return 1
  393. if pkgName == "":
  394. pkgName = manifestRoot.attrib["package"]
  395. printlog("get pkg name:%s ----------------------------" % pkgName)
  396. else:
  397. oldPkgName = manifestRoot.attrib["package"]
  398. content = open("%s/AndroidManifest.xml" % apkPath, "r").read()
  399. content = content.replace(oldPkgName, pkgName)
  400. printlog("content ---------------------------------")
  401. printlog(content)
  402. open("%s/AndroidManifest.xml" % apkPath, "w").write(content)
  403. printlog("old pkg name:%s ----------------------------" % oldPkgName)
  404. printlog("new pkg name:%s ----------------------------" % pkgName)
  405. # open("tmp/AndroidManifest.xml","w").write(content)
  406. # manifestRoot.attrib["package"] = pkgName
  407. createRFileCmd = "%s/aapt%s p -m -J %s/gen -M %s/AndroidManifest.xml -I %s/android.jar -S %s/res " % (
  408. apk_utils.getComplieToolsHome(), SUFFIX_EXE, tempDir, apkPath, apk_utils.getToolsJarHome(), tempDir)
  409. printlog("createRFileCmd:%s" % createRFileCmd)
  410. if os.system(createRFileCmd) != 0:
  411. return 1
  412. sourcePath = pkgName.replace(".", "/")
  413. createRClassCmd = "%s/javac -encoding utf-8 %s/gen/%s/R.java" % (apk_utils.getJavaBinPath(), tempDir, sourcePath)
  414. printlog("createRClassCmd:%s" % createRClassCmd)
  415. if os.system(createRClassCmd) != 0:
  416. return 1
  417. createDexCmd = "%s/dx%s --dex --output %s/classes.dex %s/gen" % (
  418. apk_utils.getSdkBuildToolPath(), SUFFIX_BAT, tempDir, tempDir)
  419. printlog("createDexCmd:%s" % createDexCmd)
  420. if os.system(createDexCmd) != 0:
  421. return 1
  422. dex2smaliCmd = "%s/java -jar %s/baksmali-2.1.0.jar -o %s/smali %s/classes.dex" % (
  423. apk_utils.getJavaBinPath(), apk_utils.getToolsJarHome(), apkPath, tempDir)
  424. printlog("dex2smaliCmd:%s" % dex2smaliCmd)
  425. if os.system(dex2smaliCmd) != 0:
  426. return 1
  427. printlog("finished compiling resources -----------------------------------")
  428. return 0
  429. def mergeYml(fromfile, tofile):
  430. if not os.path.exists(fromfile):
  431. return False, "origin yaml file is not exists"
  432. if not os.path.exists(tofile):
  433. return False, "destination yaml file is not exists"
  434. header = "!!brut.androlib.meta.MetaInfo\n"
  435. fromcontent = open(fromfile, "r").read()
  436. fromcontent = fromcontent.replace(header, "")
  437. tocontent = open(tofile, "r").read()
  438. tocontent = tocontent.replace(header, "")
  439. fromroot = yaml.safe_load(fromcontent)
  440. toroot = yaml.safe_load(tocontent)
  441. if fromroot == None:
  442. printlog("from root is empty")
  443. return False, "orgin yaml file cant not be parsed or empty"
  444. if toroot == None:
  445. printlog("to root is empty")
  446. return False, "destination yaml file cant not be parsed or is empty"
  447. donotcompresskey = "doNotCompress"
  448. if donotcompresskey in fromroot:
  449. arr = fromroot[donotcompresskey]
  450. if not donotcompresskey in toroot:
  451. toroot[donotcompresskey] = arr
  452. else:
  453. toarr = toroot[donotcompresskey]
  454. toroot[donotcompresskey] = list(set(toarr + arr))
  455. unknownfileskey = "unknownFiles"
  456. if unknownfileskey in fromroot:
  457. fromunknownfilesarr = fromroot[unknownfileskey]
  458. else:
  459. fromunknownfilesarr = {}
  460. tounknownfilesarr = toroot[unknownfileskey]
  461. toroot[unknownfileskey] = dict(fromunknownfilesarr.items()).update(tounknownfilesarr.items())
  462. desfile = open(tofile, "w")
  463. desfile.writelines(header)
  464. yaml.safe_dump(toroot, desfile, default_flow_style=False)
  465. return True, ""
  466. pass