def portingFiles(self, commit, filesChanged, dstDir): """ Generate patch files for porting """ # Reset to the commit self.reset(commit) Log.i( TAG, "Generating %s from %s at commit %s" % (dstDir, self.basePath, commit)) if not os.path.exists(dstDir): os.makedirs(dstDir) # Copy changed items from source for item in filesChanged: src = os.path.join(self.basePath, item) dst = os.path.join(dstDir, item) if os.path.exists(src): # Only copy files in FRAMEWORK_JARS if not Utils.isInFramework(item): continue # We need to format the SMALI file. # Copy all the sub classes even if no change. Utils.copyWholly(src, os.path.dirname(dst)) Utils.combineFrameworkPartitions(dstDir)
def combineFrameworkPartitions(frameworkDir): """ Combine framework partitions into framework.jar.out. """ # For Android 5.0, handle dex partitions. dst = os.path.join(frameworkDir, "framework.jar.out", "smali") partitionPath = os.path.join(frameworkDir, "framework.jar.out", "smali_classes2") if os.path.exists(partitionPath): Log.i(TAG, "Combine %s into framework.jar.out/smali" % partitionPath) for subDir in os.listdir(partitionPath): src = os.path.join(partitionPath, subDir) Utils.run(["cp", "-r", src, dst], stdout=subprocess.PIPE).communicate() shutil.rmtree(partitionPath) # For Android Handle framework partitions for partition in PARTITIONS: if partition == "framework.jar.out": continue partitionPath = os.path.join(frameworkDir, partition) if os.path.exists(partitionPath): Log.i(TAG, "Combine %s into framework.jar.out" % partition) src = os.path.join(partitionPath, "smali") dst = os.path.join(frameworkDir, "framework.jar.out") Utils.run(["cp", "-r", src, dst], stdout=subprocess.PIPE).communicate() shutil.rmtree(partitionPath)
def printSubprocessOut(subp): while True: buff = subp.stdout.readline().strip('\n') if buff == '' and subp.poll() != None: break Log.i(TAG, buff)
def decode(baiduZip, out): """ Decode FRAMEWORK_JARS in baidu.zip into out directory. """ Log.i(TAG, "Generating %s from %s" % (out, baiduZip)) # Phase 1: deodex deodexZip = Utils.deodex(baiduZip) if deodexZip == None: return # Phase 2: decode framework jars temp = tempfile.mkdtemp() Log.i(TAG, "unzip %s to %s" % (deodexZip, temp)) subp = Utils.run(["unzip", "-q", "-o", deodexZip, "-d", temp], stdout=subprocess.PIPE) subp.communicate() if not os.path.exists(out): os.makedirs(out) Utils.decodeAPKandJAR(temp, out) shutil.rmtree(temp) # Phase 3: combine framework partitions Utils.combineFrameworkPartitions(out)
def out(self, outDir=None): if outDir is None: outDir = self.mOutDir for itype in self.mImgDict.keys(): outFile = os.path.join(outDir, "%s.img" % (itype)) shutil.copyfile(self.mImgDict[itype], outFile) Log.i(LOG_TAG, "Out: %s" % (outFile)) shutil.rmtree(self.mWorkdir)
def writeXML(dom): # tree = ET.ElementTree(root) # tree.write(ChangeList.PATCH_XML, #pretty_print=True, # xml_declaration=True, encoding='utf-8') f = open(ChangeList.PATCH_XML, 'w') dom.writexml(f, addindent=' ', newl='\n', encoding='utf-8') f.close() Log.i(TAG, "%s is generated" % ChangeList.PATCH_XML)
def __init__(self): """ baseName is the short device name """ Log.i(TAG, "Start preparing essential files in %s" % Config.AUTOPATCH) self.baseDevice = BaseDevice(OPTIONS.baseName) if OPTIONS.patchXml == Config.PATCHALL_XML: self.patchall() elif OPTIONS.patchXml == Config.UPGRADE_XML: self.upgrade() elif OPTIONS.patchXml == Config.PORTING_XML: self.porting()
def bosp(self, bospDst, force=True): """ Prepare BOSP, set force to be False to not generate again if exists. """ if force: subp = Utils.run(["rm", "-rf", bospDst], stdout=subprocess.PIPE) subp.communicate() Log.i(TAG, "Generating %s from %s" % (bospDst, self.basePath)) Utils.copyAPKandJAR(self.basePath, bospDst, self.target_is_ab_system())
def make(self, force=True): """ Generate the change list into XML. Set force as False not to generate again if exists. """ if not force and os.path.exists(ChangeList.PATCH_XML): Log.d(TAG, "Using the existing %s" % ChangeList.PATCH_XML) return True Log.i(TAG, "Generating %s" % ChangeList.PATCH_XML) hasChange = ChangeList.XMLFromDiff() return hasChange
def __pull__(self): bootEntry = mtkEntry(imagetype.BOOT, self.mFstab.getEntry(imagetype.BOOT)) Log.i(LOG_TAG, "Try to pull boot partition from device ...") adBoot = AndroidFile(bootEntry.mMp) adBoot.pull(self.mBootImg, bootEntry.mStart, bootEntry.mSize) recoveryEntry = mtkEntry(imagetype.RECOVERY, self.mFstab.getEntry(imagetype.RECOVERY)) Log.i(LOG_TAG, "Try to pull recovery partition from device ...") adRecovery = AndroidFile(recoveryEntry.mMp) adRecovery.pull(self.mRecoveryImg, recoveryEntry.mStart, recoveryEntry.mSize)
def aosp(self, aospDst): """ Prepare AOSP to asopDst """ aospSrc = os.path.join(self.basePath, "vendor/aosp") # If no AOSP under vendor/ , decode them out if not os.path.exists(aospSrc): os.makedirs(aospSrc) vendorRoot = os.path.join(self.basePath, "vendor") Utils.decodeAPKandJAR(vendorRoot, aospSrc) if not os.path.exists(aospDst): Log.i(TAG, "Generating %s from %s" % (aospDst, aospSrc)) Utils.copyAPKandJAR(aospSrc, aospDst, self.target_is_ab_system())
def combineFrameworkPartitions(frameworkDir): """ Combine framework partitions into framework.jar.out. """ for partition in PARTITIONS: if partition == "framework.jar.out": continue partitionPath = os.path.join(frameworkDir, partition) if os.path.exists(partitionPath): Log.i(TAG, "Combine %s into framework.jar.out" % partition) src = os.path.join(partitionPath, "smali") dst = os.path.join(frameworkDir, "framework.jar.out") subp = Utils.run(["cp", "-r", src, dst], stdout=subprocess.PIPE) subp.communicate() shutil.rmtree(partitionPath)
def push(device, fstabFile, inFile, fstab_version=1): ret = False Log.i("flash boot or recovery", "It may take a few minutes, please wait....") check() if mtkpull.isMtkDevice() and mtkpush(device, fstabFile, inFile, fstab_version).do(): Log.d("flash boot or recovery", "Success use mtkpush to flash images....") ret = True else: if push(device, fstabFile, inFile, fstab_version).do(): Log.d("flash boot or recovery", "Success to flash images....") ret = True assert ret == True, "Failed to flash image %s for %s" % (inFile, device) return ret
def __getRootShell__(): subp = subprocess.Popen(["check-su"], stdout=subprocess.PIPE) subp.communicate() if subp.returncode == 0: Log.i("AdbShell", "use su to root") return SuShell() else: Log.i("AdbShell", "Can not use su to root, assume your phone has already been root with modify default.prop in boot!") Log.i("AdbShell", "Try adb root, it may be blocked!") subp = subprocess.Popen(["adb", "root"], stdout=subprocess.PIPE) subp.communicate() Log.i("AdbShell", "Root successfull") return AdbShell()
def decodeAPKandJAR(root, out): # Format path if os.path.exists(os.path.join(root, "SYSTEM")): shutil.move(os.path.join(root, "SYSTEM"), os.path.join(root, "system")) dirname = os.path.join(root, "system/framework") Log.i(TAG, "decoding framework-res.apk") jarpath = os.path.join(dirname, "framework-res.apk") jarout = os.path.join(out, "framework-res") subp = Utils.run(["apktool", "d", "-f", jarpath, "-o", jarout], stdout=subprocess.PIPE) Utils.printSubprocessOut(subp) for jarname in FRAMEWORK_JARS: jarpath = os.path.join(dirname, jarname) if os.path.exists(jarpath): Log.i(TAG, "decoding %s" % jarname) jarout = os.path.join(out, jarname + ".out") subp = Utils.run(["apktool", "d", "-f", jarpath, "-o", jarout], stdout=subprocess.PIPE) Utils.printSubprocessOut(subp)
def decode(boardZip, out): """ Decode FRAMEWORK_JARS in board.zip into out directory. """ Log.i(TAG, "Generating %s from %s" % (out, boardZip)) # Phase 1: normalize temp = Utils.otaNormalize(boardZip) if temp == None: Log.e(TAG, "decode(): ota normalized failed") return if not os.path.exists(out): os.makedirs(out) Utils.decodeAPKandJAR(temp, out) shutil.rmtree(temp) # Phase 3: combine framework partitions Utils.combineFrameworkPartitions(out) # Phase 4: remove useless files Utils.removeUseless(out)
def getAdPartitions(self, minsize, maxsize): adPt = AndroidFile(pull.PROC_PARTITIONS) assert adPt.exist(), "File %s is not exist in phone!" % ( pull.PROC_PARTITIONS) outAdDict = {} Log.i(LOG_TAG, "Try to create block of partitions ...") for etr in adPt.read().splitlines(): stripEtr = etr.strip("\n") if len(stripEtr) > 0 and stripEtr[0] != "#": splitArray = stripEtr.split() if len(splitArray) == 4: try: blkSize = string.atoi(splitArray[2]) except: continue blkName = splitArray[3] adBlk = AndroidFile("%s/%s" % (pull.BLOCK_DIR, blkName)) if blkSize >= minsize and blkSize <= maxsize and adBlk.exist( ): outAdDict[blkName] = adBlk Log.i(LOG_TAG, "Create block of partitions done!") return outAdDict
def deodex(baiduZip): """ Deodex the baidu.zip. The deodexed with suffix "deodex.zip" is returned if succeed. """ if not os.path.exists(baiduZip): Log.e(TAG, "deodex() % not exists" % baiduZip) return None deodexZip = baiduZip + ".deodex.zip" if os.path.exists(deodexZip): Log.d(TAG, "deodex() %s already exists" % deodexZip) return deodexZip DEODEX_THREAD_NUM = "4" Log.i(TAG, "Deodex %s" % baiduZip) subp = Utils.run(["deodex", "-framework", baiduZip, DEODEX_THREAD_NUM], stdout=subprocess.PIPE) Utils.printSubprocessOut(subp) if not os.path.exists(deodexZip): Log.e(TAG, "deodex() deodex %s failed!" % baiduZip) return None return deodexZip
def __pull__(self, adDict): Log.i(LOG_TAG, "Pull blocks from device ...") for blkName in adDict.keys(): pcOut = os.path.join(self.mWorkdir, blkName) Log.i(LOG_TAG, "Pull %s to %s" % (blkName, pcOut)) if adDict[blkName].pull(pcOut): Log.i(LOG_TAG, "...") img = imagetype.imagetype(pcOut) itype = img.getType() if itype is not None: self.mImgDict[itype] = pcOut img.exit() if len(self.mImgDict.keys()) >= 2: # both boot and rec had found return
def pull(outDir): ret = False Log.i( LOG_TAG, "Begin pull boot and recovery, make sure your phone was connected and adb devices is fine!" ) Log.i(LOG_TAG, "It may take a few minutes, please wait....") check() Log.i(LOG_TAG, "adb connect success.") if mtkpull.isMtkDevice() and mtkpull.do(outDir): Log.d("pull_boot_recovery", "Success use mtkpull to pull images....") ret = True else: if pull.do(outDir): Log.d("pull_boot_recovery", "Success to pull images....") ret = True assert ret == True, "Failed to pull images....."
def i(s): Log.i(SLog.TAG, s)
def d(s): if SLog.DEBUG: Log.i(SLog.TAG, s) else: Log.d(SLog.TAG, s)
def waitdevices(self, printout=DEBUG): if printout: Log.i(AdbShell.TAG, "waiting for devices....") return super(AdbShell, self).run("adb wait-for-device", None, printout)