1*f50c3066SAndroid Build Coastguard Workerimport sys, os, subprocess, ConfigParser 2*f50c3066SAndroid Build Coastguard Workerfrom optparse import OptionParser 3*f50c3066SAndroid Build Coastguard Worker 4*f50c3066SAndroid Build Coastguard Workerclass2jar = dict() 5*f50c3066SAndroid Build Coastguard Workerjars_to_process = set() 6*f50c3066SAndroid Build Coastguard Worker 7*f50c3066SAndroid Build Coastguard Workeropt_parser = OptionParser() 8*f50c3066SAndroid Build Coastguard Workeropt_parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, help="set verbosity") 9*f50c3066SAndroid Build Coastguard Workeropt_parser.add_option("-c", "--config", dest="config", default=os.path.dirname(sys.argv[0])+"/android-jar.conf", help="configuration file path") 10*f50c3066SAndroid Build Coastguard Worker(options, args) = opt_parser.parse_args() 11*f50c3066SAndroid Build Coastguard Workerif not os.path.isfile(options.config): 12*f50c3066SAndroid Build Coastguard Worker sys.exit('Error! No configuration file at: '+options.config) 13*f50c3066SAndroid Build Coastguard Workerconfig_parser = ConfigParser.SafeConfigParser() 14*f50c3066SAndroid Build Coastguard Workerconfig_parser.read(options.config) 15*f50c3066SAndroid Build Coastguard Workerajars_dir = config_parser.get('android-paths', 'aosp-out-dir') 16*f50c3066SAndroid Build Coastguard Workerstubs_jar = config_parser.get('android-paths', 'android-stubs-jar') 17*f50c3066SAndroid Build Coastguard Workerjarinfer = config_parser.get('jar-infer-paths', 'jar-infer-path') 18*f50c3066SAndroid Build Coastguard Workerwrk_dir = config_parser.get('android-model', 'wrk-dir') 19*f50c3066SAndroid Build Coastguard Workerastubx_file = config_parser.get('android-model', 'astubx-path') 20*f50c3066SAndroid Build Coastguard Worker 21*f50c3066SAndroid Build Coastguard Worker### Finding android libraries ### 22*f50c3066SAndroid Build Coastguard Workerprint "> Finding android libraries..." 23*f50c3066SAndroid Build Coastguard Worker# Since SDK 31, the directory structure mixes classes.jar and classes-header.jar files, we use 24*f50c3066SAndroid Build Coastguard Worker# only the former, as classes-header.jar files are missing methods' bytecode. 25*f50c3066SAndroid Build Coastguard Workercmd = "find " + ajars_dir + " -name \"*.jar\" | grep -v classes-header.jar" 26*f50c3066SAndroid Build Coastguard Workerajars = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True).stdout.read().splitlines() 27*f50c3066SAndroid Build Coastguard Workerfor ajar in ajars: 28*f50c3066SAndroid Build Coastguard Worker cmd = "jar tvf " + ajar + " | grep \"\.class$\" | awk '{print $8}'" 29*f50c3066SAndroid Build Coastguard Worker ajar_classes = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True).stdout.read().splitlines() 30*f50c3066SAndroid Build Coastguard Worker for ajar_class in ajar_classes: 31*f50c3066SAndroid Build Coastguard Worker if ajar_class in class2jar: 32*f50c3066SAndroid Build Coastguard Worker if options.verbose: 33*f50c3066SAndroid Build Coastguard Worker print "[Warn] Same class in multiple jars : " + ajar_class + " in " + class2jar[ajar_class] + " , " + ajar 34*f50c3066SAndroid Build Coastguard Worker else: 35*f50c3066SAndroid Build Coastguard Worker class2jar[ajar_class] = ajar 36*f50c3066SAndroid Build Coastguard Workercmd = "jar tvf " + stubs_jar + " | grep \"\.class$\" | awk '{print $8}'" 37*f50c3066SAndroid Build Coastguard Workerajar_classes = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True).stdout.read().splitlines() 38*f50c3066SAndroid Build Coastguard Workerfound = 0 39*f50c3066SAndroid Build Coastguard Workerfor ajar_class in ajar_classes: 40*f50c3066SAndroid Build Coastguard Worker if ajar_class in class2jar: 41*f50c3066SAndroid Build Coastguard Worker found += 1 42*f50c3066SAndroid Build Coastguard Worker jars_to_process.add(class2jar[ajar_class]) 43*f50c3066SAndroid Build Coastguard Worker else: 44*f50c3066SAndroid Build Coastguard Worker if options.verbose: 45*f50c3066SAndroid Build Coastguard Worker print "[Warn] Class not found in any jar : " + ajar_class 46*f50c3066SAndroid Build Coastguard Workerprint ",".join(list(jars_to_process)) 47*f50c3066SAndroid Build Coastguard Workerprint "Found " + str(found) + " / " + str(len(ajar_classes)) + " in " + str(len(jars_to_process)) + " jars" 48*f50c3066SAndroid Build Coastguard Worker 49*f50c3066SAndroid Build Coastguard Worker### Running jarinfer ### 50*f50c3066SAndroid Build Coastguard Workerprint "> Running jarinfer on android jars..." 51*f50c3066SAndroid Build Coastguard Workercmd = "java -jar " + jarinfer + " -i " + ",".join(list(jars_to_process)) + " -o " + wrk_dir + "/" + astubx_file 52*f50c3066SAndroid Build Coastguard Workerif options.verbose: 53*f50c3066SAndroid Build Coastguard Worker cmd += " -dv" 54*f50c3066SAndroid Build Coastguard Workerprint cmd 55*f50c3066SAndroid Build Coastguard Workerreturncode = subprocess.call(cmd, shell=True) 56*f50c3066SAndroid Build Coastguard Workersys.exit(returncode) 57