def instrumentApkForCoverage(self, pathToOrigApk, resultsDir=None, tmpDir=None, 
                                 removeApkTmpDirAfterInstr=True, 
                                 copyApkToRes = True):
        self._bboxStateMachine.start(STATE_UNINITIALIZED)
        
        valid = self._checkProvidedApk(pathToOrigApk)
        if not valid:
            return False
        self._bboxStateMachine.transitToState(STATE_APK_VALID)
        
        resultsRootDir = None
        if not resultsDir:
            resultsRootDir = os.path.join(os.getcwd(), RESULTS_RELATIVE_DIR)
        else:
            resultsRootDir = os.path.abspath(resultsDir)
        
        tmpRootDir = None
        if not tmpDir:
            tmpRootDir = os.path.join(os.getcwd(), TMP_RELATIVE_DIR)
        else:
            tmpRootDir = os.path.abspath(tmpDir)
        
        apkFileName = os.path.splitext(os.path.basename(pathToOrigApk))[0]
        
        self.apkTmpDir = self._createDir(tmpDir, apkFileName, False, True)
        self.apkResultsDir = self._createDir(resultsRootDir, apkFileName, False, True)
        self.coverageMetadataFolder = self._createDir(self.apkResultsDir, self.config.getCoverageMetadataRelativeDir(), False, True)
        self.runtimeReportsRootDir = self._createDir(self.apkResultsDir, self.config.getRuntimeReportsRelativeDir(), False, True)
        self._bboxStateMachine.transitToState(STATE_FOLDERS_CREATED)
        
        #coping initial apk file if required
        if copyApkToRes:
            shutil.copy2(pathToOrigApk, self.apkResultsDir)
        
        #decompiling apk into a folder
        decompileDir = os.path.join(self.apkTmpDir, self.config.getDecompiledApkRelativeDir())
        success = self._decompileApk(self.bboxInstrumenter, pathToOrigApk, decompileDir)
        if not success:
            return False
        self._bboxStateMachine.transitToState(STATE_APK_DECOMPILED)
        
        #getting all available dex files
        dexFilesRelativePaths = self._getDexFilePathsRelativeToDir(decompileDir)
        if not dexFilesRelativePaths:
            logger.error("There is no dex files to convert!")
            return False
        if "classes.dex" not in dexFilesRelativePaths:
            # "classes.dex" must be in the decompile root directory
            logger.error("There is no classes.dex file found in the list of dex files")
            return False
        
        
        #converting dex to jar files
        rawJarFilesRootDir = os.path.join(self.apkTmpDir, self.config.getTmpJarRelativeDir())
        jarFilesRelativePaths = self._convertDex2JarFiles(
                                    converter=self.bboxInstrumenter, 
                                    dexFilesRootDir=decompileDir, 
                                    dexFilesRelativePaths=dexFilesRelativePaths,
                                    jarFilesRootDir=rawJarFilesRootDir,
                                    proceedOnError=True)
        self._bboxStateMachine.transitToState(STATE_DEX_CONVERTED_TO_JAR)
        
        if "classes.jar" not in jarFilesRelativePaths:
            #main file is not converted
            logger.error("Conversion from classes.dex to classes.jar was not successful!")
            return False
        
        #instrumenting available jar files
        self.coverageMetadataFile = os.path.join(self.coverageMetadataFolder, self.config.getCoverageMetadataFilename())
        emmaInstrJarFilesRootDir = os.path.join(self.apkTmpDir, self.config.getInstrumentedFilesRelativeDir())
        emmaInstrJarFileRelativePaths = self._instrFilesWithEmma(
                            instrumenter=self.bboxInstrumenter, 
                            jarFilesRootDir=rawJarFilesRootDir, 
                            jarFilesRelativePaths=jarFilesRelativePaths, 
                            instrJarsRootDir=emmaInstrJarFilesRootDir,
                            coverageMetadataFile=self.coverageMetadataFile,
                            proceedOnError=True)
        self._bboxStateMachine.transitToState(STATE_JARS_INSTRUMENTED)
        
        if "classes.jar" not in emmaInstrJarFileRelativePaths:
            #main file is not instrumented
            logger.error("Instrumentation of classes.jar was not successful!")
            return False
        
        #converting jar files back to dex files
        instrDexFilesRelativePaths = self._convertJar2DexWithInstr(
                    converter=self.bboxInstrumenter,
                    instrJarsRootDir=emmaInstrJarFilesRootDir, 
                    instrJarFilesRelativePaths=emmaInstrJarFileRelativePaths,
                    finalDexFilesRootDir=decompileDir,
                    proceedOnError=True)
        self._bboxStateMachine.transitToState(STATE_JAR_CONVERTED_TO_DEX)
        
        if "classes.dex" not in instrDexFilesRelativePaths:
            logger.error("There is no classes.dex file found in the list of dex files")
            return False
        
        #checking what files have not been converted
        uninstrumentedFiles = self._getUnInstrFilesRelativePaths(dexFilesRelativePaths, instrDexFilesRelativePaths)
        if uninstrumentedFiles:
            logger.debug("The following files were not instrumented: %s" + str(uninstrumentedFiles))
        
        #instrument AndroidManifest.xml
        decompiledAndroidManifestPath = os.path.join(decompileDir, "AndroidManifest.xml")
        success = self._instrAndroidManifest(self.bboxInstrumenter, decompiledAndroidManifestPath)
        if not success:
            logger.error("Cannot instrument AndroidManifest.xml file!")
            return False
        #coping instrumented AndroidManifest.xml to result folder
        shutil.copy2(decompiledAndroidManifestPath, self.apkResultsDir)
        self.androidManifestFile = os.path.join(self.apkResultsDir, "AndroidManifest.xml")
        self._bboxStateMachine.transitToState(STATE_MANIFEST_INSTRUMENTED)
        
        compiledApkFilePath = os.path.join(self.apkResultsDir, "%s%s.apk" % (apkFileName, self.config.getInstrFileSuffix()))
        success = self._compileApk(self.bboxInstrumenter, decompileDir, compiledApkFilePath)
        if not success:
            logger.error("Cannot build apk!")
            return False
        self._bboxStateMachine.transitToState(STATE_INSTRUMENTED_APK_BUILD)
        
        #need to copy resources into file
        compiledApkFilePathWithEmmaRes = os.path.join(self.apkResultsDir, "%s%s.apk" % (apkFileName, self.config.getFinalInstrFileSuffix()))
        shutil.copy2(compiledApkFilePath, compiledApkFilePathWithEmmaRes)
        self._putAdditionalResources(apk=compiledApkFilePathWithEmmaRes, resources=self.config.getEmmaResourcesDir())
        self._bboxStateMachine.transitToState(STATE_FINAL_INSTRUMENTED_APK_BUILD)
        
        signedApkFilePath = os.path.join(self.apkResultsDir, "%s%s.apk" % (apkFileName, self.config.getSignedFileSuffix()))
        success = self._signApk(self.bboxInstrumenter, compiledApkFilePathWithEmmaRes, signedApkFilePath)
        if not success:
            logger.error("Cannot sign apk!")
            return False
        self._bboxStateMachine.transitToState(STATE_INSTRUMENTED_APK_SIGNED)
        
        alignedApkFilePath = os.path.join(self.apkResultsDir, "%s%s.apk" % (apkFileName, self.config.getAlignedFileSuffix()))
        success = self._alignApk(self.bboxInstrumenter, signedApkFilePath, alignedApkFilePath)
        if not success:
            logger.error("Cannot align apk!")
            return False
        self._bboxStateMachine.transitToState(STATE_INSTRUMENTED_APK_ALIGNED)
        
        #cleaning: if tmp dir needs to be removed after instrumentation
        if removeApkTmpDirAfterInstr:
            shutil.rmtree(self.apkTmpDir)
        
        self.instrumentedApk = alignedApkFilePath
        self.androidManifest = AndroidManifest(self.androidManifestFile)
        self.packageName = self.androidManifest.getInstrumentationTargetPackage()
        self.runnerName = self.androidManifest.getInstrumentationRunnerName()
        
        #Final node transition
        self._bboxStateMachine.transitToState(STATE_APK_INSTRUMENTED)
        return True
Return the minimum interparticle distance in a cloud of points
dataset/ETHPy150Open zyrikby/BBoxTester/BBoxTester/bboxcoverage.py/BBoxCoverage.instrumentApkForCoverage--crossover with--dataset/ETHPy150Open enthought/mayavi/mayavi/tools/tools.py/_min_axis_distance