def dump(self): Log.d(TAG, "prepare = %s" % str(self.prepare)) Log.d( TAG, "baseName = %s, patchXml = %s, olderRoot = %s, newerRoot = %s, commit1 = %s, commit2 = %s" % (self.baseName, self.patchXml, self.olderRoot, self.newerRoot, self.commit1, self.commit2))
def porting(self): """ Porting changes from commit1 to commit2 commit is 7 bits """ # Phase 1: get the lower and upper commit commitModel = CommitModel(self.baseDevice) (lowerCommit, upperCommit) = commitModel.getCommitRange(OPTIONS.commit1, OPTIONS.commit2) Log.d( TAG, "Porting.prepare(). lowerCommit = %s, upperCommit = %s" % (lowerCommit, upperCommit)) # Phase 2: Prepare the older and newer root if OPTIONS.patchXml == Config.PORTING_XML: OPTIONS.newerRoot = os.path.join( Config.AUTOPATCH, "%s_newer_%s" % (self.baseDevice.name(), upperCommit)) OPTIONS.olderRoot = os.path.join( Config.AUTOPATCH, "%s_older_%s" % (self.baseDevice.name(), lowerCommit)) filesChanged = self.baseDevice.getFilesChanged(lowerCommit, upperCommit) self.baseDevice.portingFiles(upperCommit, filesChanged, OPTIONS.newerRoot) self.baseDevice.portingFiles(lowerCommit, filesChanged, OPTIONS.olderRoot) # Phase 3: Restore the commit model commitModel.restore() # Phase 4: prepare patch XML ChangeList(OPTIONS.olderRoot, OPTIONS.newerRoot, OPTIONS.patchXml).make(force=True)
def appendPart(self, part): """ Append a part to list if not exist """ try: self.mPartList.index(part) except: Log.d(TAG, " [Add new part %s ] " % part) self.mPartList.append(part)
def deletePart(self, part): """ Delete a part """ try: self.mPartList.remove(part) Log.d(TAG, " [Delete part %s ] " % part) except: Log.e(TAG, "SmaliSpliiter.deltePart(): can not find part %s" % part)
def isInFramework(filepath): """ Is the file path in jars defined in FRAMEWORK_JARS """ relRoot = filepath.split("/")[0] result = relRoot[0:-4] in FRAMEWORK_JARS Log.d( TAG, "Utils.isInFramework(): %s, %s -> %s" % (result, filepath, relRoot)) return result
def replacePart(self, targetPart, newerPart): """ Replace the target with the newer. """ try: index = self.mPartList.index(targetPart) self.mPartList[index] = newerPart Log.d(TAG, " [Replace %s by %s] " % (targetPart, newerPart)) except: Log.e( TAG, "SmaliSplitter.replacePart() can not find part %s" % targetPart)
def __init__(self): ''' Constructor ''' super(mtkpull, self).__init__() self.mFstabConfig = fstabconfig(mtkpull.getFstabconfigFile()) self.mFstab = fstab(AndroidFile(mtkpull.MTK_DUMCHAR_INFO), self.mFstabConfig) Log.d(LOG_TAG, "work dir: %s" % (self.mWorkdir)) self.mBootImg = os.path.join(self.mWorkdir, "boot.img") self.mRecoveryImg = os.path.join(self.mWorkdir, "recovery.img")
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 conflictPart(self, olderPart, newerPart): """ If older and newer are the same content, no conflict happen. Otherwise, mark out conflict. """ # Get older part content olderHandle = open(olderPart, "rb") olderContent = olderHandle.read() olderHandle.close() # Get newer part content newerHandle = open(newerPart, "r+") newerContent = newerHandle.read() # Compare older and newer content if olderContent == newerContent: # No need to handle access any more # # BOSP has no change on AOSP. # # Still handle this case: "access$" method # if newerPart.find("access$") >= 0: # Log.d(TAG, " [Might useful access part %s ] " % newerPart) # # lines = [] # lines.append("\n# Remove the first '#' if you want to enable this method. It might be invoked from codes of BOSP.\n") # for line in newerContent.splitlines(): # if len(line) > 0: line = "#%s\n" % line # lines.append(line) # # newerHandle.seek(0) # newerHandle.truncate() # newerHandle.writelines(lines) # newerHandle.close() # self.mPartList.append(newerPart) # else: # newerHandle.close() newerHandle.close() else: # BOSP has changes on AOSP. # Conflict happened Log.d(TAG, " [Conflict part %s ] " % newerPart) # Mark out the conflict newerContent = "\n<<<<<<< VENDOR\n=======%s\n>>>>>>> BOSP\n" % newerContent newerHandle.seek(0) newerHandle.truncate() newerHandle.write(newerContent) newerHandle.close() self.mPartList.append(newerPart)
def porting(self): """ Porting changes from commit1 to commit2 commit is 7 bits """ # Phase 1: get the lower and upper commit commitModel = CommitModel(self.baseDevice) (lowerCommit, upperCommit) = commitModel.getCommitRange(OPTIONS.commit1, OPTIONS.commit2) Log.d( TAG, "Porting.prepare(). lowerCommit = %s, upperCommit = %s" % (lowerCommit, upperCommit)) # Phase 2: Prepare the older and newer root if OPTIONS.patchXml == Config.PORTING_XML: OPTIONS.newerRoot = os.path.join( Config.AUTOPATCH, "%s_newer_%s" % (self.baseDevice.name(), upperCommit)) OPTIONS.olderRoot = os.path.join( Config.AUTOPATCH, "%s_older_%s" % (self.baseDevice.name(), lowerCommit)) filesChanged = self.baseDevice.getFilesChanged(lowerCommit, upperCommit) self.baseDevice.portingFiles(upperCommit, filesChanged, OPTIONS.newerRoot) self.baseDevice.portingFiles(lowerCommit, filesChanged, OPTIONS.olderRoot) # Phase 3: Restore the commit model commitModel.restore() # Phase 4: prepare patch XML # TODO Fix upgrade no wifi-service.jar.out # Temporary solution, remove the following code later wifi_service = os.path.join(OPTIONS.olderRoot, "wifi-service.jar.out") if not os.path.exists(wifi_service): src = os.path.join(self.baseDevice.basePath, "vendor/aosp/wifi-service.jar.out") if os.path.exists(src): subp = Utils.run(["cp", "-r", src, OPTIONS.olderRoot], stdout=subprocess.PIPE) subp.communicate() # Temporary solution, remove the above code later ChangeList(OPTIONS.olderRoot, OPTIONS.newerRoot, OPTIONS.patchXml).make(force=True)
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 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 copyAPKandJAR(src, dst, targetAbSystem): if not os.path.exists(dst): os.makedirs(dst) baseRootPath = os.path.join(src, "ROOT") baseBootPath = os.path.join(src, "boot.img.out") baseRamDisk = os.path.join(baseBootPath, "RAMDISK") dstRootPath = os.path.join(dst, "ROOT") dstBootPath = os.path.join(dst, "boot.img.out") dstRamDisk = os.path.join(dstBootPath, "RAMDISK") baseAbSystem = os.path.exists(baseRootPath) if baseAbSystem: if targetAbSystem: subp = Utils.run(["cp", "-r", baseRootPath, dst], stdout=subprocess.PIPE) else: os.makedirs(dstBootPath) subp = Utils.run(["cp", "-r", baseRootPath, dstRamDisk], stdout=subprocess.PIPE) else: if targetAbSystem: subp = Utils.run(["cp", "-r", baseRamDisk, dstRootPath], stdout=subprocess.PIPE) else: subp = Utils.run(["cp", "-r", baseBootPath, dst], stdout=subprocess.PIPE) subp.communicate() frwRes = os.path.join(src, "framework-res") subp = Utils.run(["cp", "-r", frwRes, dst], stdout=subprocess.PIPE) subp.communicate() for jarname in FRAMEWORK_JARS: jarname += ".out" srcJar = os.path.join(src, jarname) if os.path.exists(srcJar): Log.d( TAG, "Utils.copyAPKandJAR(). copying %s to %s" % (srcJar, dst)) subp = Utils.run(["cp", "-r", srcJar, dst], stdout=subprocess.PIPE) subp.communicate() Utils.combineFrameworkPartitions(dst)
def copyWholly(srcFilePath, dstDirname): """ Copy whole SMALI files which are in the same JAVA file Especially for the case of inner class, it has '$' in file path """ if not os.path.exists(dstDirname): os.makedirs(dstDirname) # Copy all the sub classes even if no change. # We need to format the SMALI file pos = srcFilePath.find("$") if pos > 0: srcFilePath = srcFilePath[0:pos] + "*" elif srcFilePath.endswith(".smali"): srcFilePath = srcFilePath.rstrip(".smali") + "*" # Note: Do not use commands.mkarg here cmd = "cp %s %s" % (srcFilePath, dstDirname) Log.d(TAG, "Utils.copyWholly(): %s" % cmd) commands.getstatusoutput(cmd)
def handle(self, argv): if len(argv) == 1: Options.usage() try: (opts, args) = getopt.getopt(argv[1:], "hlputb:c1:c2:", \ [ "help", "loosely", "patchall", "upgrade", "porting", "base=", "commit1=", "commit2=" ]) Log.d(TAG, "Program args = %s" % args) except getopt.GetoptError: Options.usage() for name, value in opts: if name in ("--help", "-h"): Options.usage() elif name in ("--loosely", "-l"): self.prepare = False elif name in ("--patchall", "-p"): self.patchXml = Config.PATCHALL_XML self.olderRoot = Config.AOSP_ROOT self.newerRoot = Config.BOSP_ROOT elif name in ("--upgrade", "-u"): self.patchXml = Config.UPGRADE_XML self.olderRoot = Config.LAST_BOSP_ROOT self.newerRoot = Config.BOSP_ROOT elif name in ("--porting", "-t"): # The older and newer root are generated by the commit1 and commit2 self.patchXml = Config.PORTING_XML elif name in ("--base", "-b"): if len(value) > 0: self.baseName = value elif name in ("--commit1", "-1"): if len(value) > 0: self.commit1 = value elif name in ("--commit2", "-2"): if len(value) > 0: self.commit2 = value self.dump() return self
def run(cmd): """ Run command in shell. Set `isMakeCommand` to True if command is a `make` command """ subp = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) output = None while True: buff = subp.stdout.readline().strip('\n') print buff if buff == '' and subp.poll() != None: break output = buff Log.d(TAG, "Shell.run() %s return %s" %(cmd, subp.returncode)) status = Shell.parseHelpStatus(subp.returncode, "%s" %output) return status
def copyAPKandJAR(src, dst): if not os.path.exists(dst): os.makedirs(dst) frwRes = os.path.join(src, "framework-res") subp = Utils.run(["cp", "-r", frwRes, dst], stdout=subprocess.PIPE) subp.communicate() for jarname in FRAMEWORK_JARS: jarname += ".out" srcJar = os.path.join(src, jarname) if os.path.exists(srcJar): Log.d( TAG, "Utils.copyAPKandJAR(). copying %s to %s" % (srcJar, dst)) subp = Utils.run(["cp", "-r", srcJar, dst], stdout=subprocess.PIPE) subp.communicate() Utils.combineFrameworkPartitions(dst)
def getLastAndOrigHead(self): """ Get the last head and the origin head of input device. """ # If last or orig head not exists, write the current head into them. head = self.parseHeadCommit() if not os.path.exists(self.lastHeadPath): BaseDevice.writeCommit(self.lastHeadPath, head) if not os.path.exists(self.origHeadPath): BaseDevice.writeCommit(self.origHeadPath, head) # Check whether need to update the lastHead and origHead oldOrigHead = BaseDevice.readCommit(self.origHeadPath) newOrigHead = head if oldOrigHead == newOrigHead: Log.d(TAG, "BaseDevice.getLastAndOrigHead(). oldOrig == newOrig") pass else: Log.d( TAG, "BaseDevice.getLastAndOrigHead(). oldOrig -> LAST_HEAD, newOrig -> ORIG_HEAD" ) BaseDevice.writeCommit(self.lastHeadPath, oldOrigHead) BaseDevice.writeCommit(self.origHeadPath, newOrigHead) lastHead = BaseDevice.readCommit(self.lastHeadPath) origHead = BaseDevice.readCommit(self.origHeadPath) Log.d( TAG, "BaseDevice.getLastAndOrigHead(). lastHead = %s, origHead = %s" % (lastHead, origHead)) return (lastHead, origHead)
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 parseHelpStatus(status, output): """ Parse the error number in `make` command output """ # GNU make exits with a status of zero if all makefiles were successfully parsed and no targets that were built failed. # A status of one will be returned if the -q flag was used and make determines that a target needs to be rebuilt. # A status of two will be returned if any errors were encountered. errRegex = re.compile("^make: .* Error (?P<errNo>(?!.*(ignored)).*)") match = errRegex.search(output) if match != None: Log.d(TAG, "Shell.parseHelpStatus() Target in GNU make") status = int(match.group("errNo")) Log.d(TAG, "Shell.parseHelpStatus() Output is %s" % output) Log.d(TAG, "Shell.parseHelpStatus() Status is %d" % status) return status
def d(s): if SLog.DEBUG: Log.i(SLog.TAG, s) else: Log.d(SLog.TAG, s)