def main(args): argc = len(args) if argc < 5 or args[1]=='--help': print "Usage: %s <name> <id> <directory> [iphone,android,mobileweb] [android_sdk]" % os.path.basename(args[0]) sys.exit(1) name = args[1].decode("utf-8") appid = args[2].decode("utf-8") directory = os.path.abspath(os.path.expanduser(args[3].decode("utf-8"))) iphone = False android = False android_sdk = None sdk = None mobileweb = False if args[4] == 'iphone' or (argc > 5 and args[5] == 'iphone') or (argc > 6 and args[6] == 'iphone'): iphone = True if args[4] == 'android' or (argc > 5 and args[5] == 'android') or (argc > 6 and args[6] == 'android'): android = True if args[4] == 'mobileweb' or (argc > 5 and args[5] == 'mobileweb') or (argc > 6 and args[6] == 'mobileweb'): mobileweb = True if android: sys.path.append(os.path.join(os.path.dirname(args[0]), "android")) from androidsdk import AndroidSDK android_sdk = args[argc-1].decode("utf-8") try: sdk = AndroidSDK(android_sdk) except Exception, e: print >>sys.stderr, e sys.exit(1)
def main(args, update_platforms=False): argc = len(args) if argc < 5 or args[1]=='--help': parser.print_help() sys.exit(1) name = args[1].decode("utf-8") appid = args[2].decode("utf-8") directory = os.path.abspath(os.path.expanduser(args[3].decode("utf-8"))) iphone = False android = False android_sdk = None sdk = None mobileweb = False blackberry = False blackberry_ndk = None if is_iphone(args[4]) or (argc > 5 and is_iphone(args[5])) or (argc > 6 and is_iphone(args[6])): iphone = True if args[4] == 'android' or (argc > 5 and args[5] == 'android') or (argc > 6 and args[6] == 'android'): android = True if args[4] == 'mobileweb' or (argc > 5 and args[5] == 'mobileweb') or (argc > 6 and args[6] == 'mobileweb'): mobileweb = True if args[4] == 'blackberry' or (argc > 5 and args[5] == 'blackberry') or (argc > 6 and args[6] == 'blackberry'): blackberry = True if android: sys.path.append(os.path.join(os.path.dirname(args[0]), "android")) from androidsdk import AndroidSDK android_sdk = args[argc-1].decode("utf-8") try: sdk = AndroidSDK(android_sdk) except Exception, e: print >>sys.stderr, e sys.exit(1)
def main(args): global android_sdk # command platform project_dir command = args[1] platform = args[2] project_dir = os.path.expanduser(args[3]) manifest = Manifest(os.path.join(project_dir, 'manifest')) error = False if is_android(platform): build_properties = read_properties( open(os.path.join(project_dir, 'build.properties'))) android_sdk_path = os.path.dirname( os.path.dirname(build_properties['android.platform'])) android_sdk = AndroidSDK(android_sdk_path) if command == 'run': def run_callback(gen_project_dir): script = os.path.abspath( os.path.join(template_dir, '..', platform, 'builder.py')) script_args = [script, 'run', gen_project_dir] if is_android(platform): script_args.append(android_sdk.get_android_sdk()) rc = run_python(script_args) # run the project if rc == 1: if is_ios(platform): error = os.path.join(gen_project_dir, 'build', 'iphone', 'build', 'build.log') print "[ERROR] Build Failed. See: %s" % os.path.abspath( error) else: print "[ERROR] Build Failed." stage(platform, project_dir, manifest, run_callback) elif command == 'run-emulator': if is_android(platform): def run_emulator_callback(gen_project_dir): script = os.path.abspath( os.path.join(template_dir, '..', platform, 'builder.py')) run_python([ script, 'run-emulator', gen_project_dir, android_sdk.get_android_sdk() ]) stage(platform, project_dir, manifest, run_emulator_callback) elif command == 'docgen': if is_android(platform): dest_dir = args[4] docgen(project_dir, dest_dir) if error: sys.exit(1) else: sys.exit(0)
def __init__(self, name, sdk, project_dir, support_dir, app_id): self.top_dir = project_dir self.project_dir = os.path.join(project_dir,'build','android') # this is hardcoded for now self.sdk = AndroidSDK(sdk, 4) self.name = name self.app_id = app_id self.support_dir = support_dir # we place some files in the users home if platform.system() == "Windows": self.home_dir = os.path.join(os.environ['USERPROFILE'], '.titanium') self.android_home_dir = os.path.join(os.environ['USERPROFILE'], '.android') else: self.home_dir = os.path.join(os.path.expanduser('~'), '.titanium') self.android_home_dir = os.path.join(os.path.expanduser('~'), '.android') if not os.path.exists(self.home_dir): os.makedirs(self.home_dir) self.sdcard = os.path.join(self.home_dir,'android.sdcard') self.classname = "".join(string.capwords(self.name).split(' '))
def main(args): global android_sdk # command platform project_dir command = args[1] platform = args[2] project_dir = os.path.expanduser(args[3]) manifest = Manifest(os.path.join(project_dir, 'manifest')) error = False if is_android(platform): build_properties = read_properties(open(os.path.join(project_dir, 'build.properties'))) android_sdk_path = os.path.dirname(os.path.dirname(build_properties['android.platform'])) android_sdk = AndroidSDK(android_sdk_path) if command == 'run': def run_callback(gen_project_dir): script = os.path.abspath(os.path.join(template_dir, '..', platform,'builder.py')) script_args = [script, 'run', gen_project_dir] if is_android(platform): script_args.append(android_sdk.get_android_sdk()) rc = run_python(script_args) # run the project if rc==1: if is_ios(platform): error = os.path.join(gen_project_dir, 'build', 'iphone', 'build', 'build.log') print "[ERROR] Build Failed. See: %s" % os.path.abspath(error) else: print "[ERROR] Build Failed." stage(platform, project_dir, manifest, run_callback) elif command == 'install': def install_callback(gen_project_dir): if is_ios(platform): print "[ERROR] Build Failed. Install module to device not supported on iOS." return tiapp_xml = os.path.join(gen_project_dir, 'tiapp.xml') script = os.path.abspath(os.path.join(template_dir, '..', platform, 'builder.py')) script_args = [script, "install", manifest.name, android_sdk.get_android_sdk(), gen_project_dir, manifest.moduleid, "Necessary argument, but unused."] rc = run_python(script_args) # install the project if rc != 0: if is_ios(platform): error = os.path.join(gen_project_dir, 'build', 'iphone', 'build', 'build.log') print "[ERROR] Build Failed. See: %s" % os.path.abspath(error) else: print "[ERROR] Build Failed." stage(platform, project_dir, manifest, install_callback) elif command == 'run-emulator': if is_android(platform): def run_emulator_callback(gen_project_dir): script = os.path.abspath(os.path.join(template_dir, '..', platform, 'builder.py')) run_python([script, 'run-emulator', gen_project_dir, android_sdk.get_android_sdk()]) stage(platform, project_dir, manifest, run_emulator_callback) elif command == 'docgen': if is_android(platform): dest_dir = args[4] docgen(project_dir, dest_dir) if error: sys.exit(1) else: sys.exit(0)
if f is not None: f.close() # Don't override a pre-existing .gitignore in case users have their own preferences # for what should be in it. (LH #2446) if not os.path.exists(os.path.join(app_dir, '.gitignore')): self.render(template_dir, 'gitignore', app_dir, '.gitignore') else: print "[TRACE] Skipping copying gitignore -> .gitignore because already exists" android_project_resources = os.path.join(project_dir, 'Resources', 'android') if build_time == False and os.path.exists(android_project_resources): shutil.rmtree(android_project_resources) if not os.path.exists(android_project_resources): copy_resources(os.path.join(template_dir, 'resources'), android_project_resources) if __name__ == '__main__': # this is for testing only for the time being if len(sys.argv) != 5 or sys.argv[1] == '--help': print "Usage: %s <name> <id> <directory> <sdk>" % os.path.basename( sys.argv[0]) sys.exit(1) sdk = AndroidSDK(sys.argv[4]) android = Android(sys.argv[1], sys.argv[2], sdk, None, 'java') android.create(sys.argv[3])
name = None theid = None for line in run.run([sdk.get_android(),'list','target'],debug=False).split("\n"): line = line.strip() if line.find("id: ")!=-1: theid = line[4:] theid = theid[0:theid.find('or ')-1] if line.find("Name:")!=-1: name = line[6:] elif line.find("Based on ")!=-1: version = line[9:] version = version[0:version.find('(')-1] name = "%s %s" % (name,version) elif line.find("Skins: ")!=-1: skins = line[7:].replace(' (default)','').strip().split(", ") avds.append({'name':name,'id':theid,'skins':skins}) return avds if __name__ == '__main__': if len(sys.argv) != 2: print "Usage: %s <directory>" % os.path.basename(sys.argv[0]) sys.exit(1) sdk = AndroidSDK(os.path.expanduser(dequote(sys.argv[1])), 7) print get_avds(sdk)
class Builder(object): def __init__(self, name, sdk, project_dir, support_dir, app_id): self.top_dir = project_dir self.project_dir = os.path.join(project_dir,'build','android') # this is hardcoded for now self.sdk = AndroidSDK(sdk, 4) self.name = name self.app_id = app_id self.support_dir = support_dir # we place some files in the users home if platform.system() == "Windows": self.home_dir = os.path.join(os.environ['USERPROFILE'], '.titanium') self.android_home_dir = os.path.join(os.environ['USERPROFILE'], '.android') else: self.home_dir = os.path.join(os.path.expanduser('~'), '.titanium') self.android_home_dir = os.path.join(os.path.expanduser('~'), '.android') if not os.path.exists(self.home_dir): os.makedirs(self.home_dir) self.sdcard = os.path.join(self.home_dir,'android.sdcard') self.classname = "".join(string.capwords(self.name).split(' ')) def wait_for_device(self,type): print "[DEBUG] Waiting for device to be ready ..." sys.stdout.flush() t = time.time() while True: output = run.run([self.sdk.get_adb(),"-%s" % type, 'devices'],True) print "[TRACE] wait_for_device returned: %s" % output if output != None: if output.find("emulator-")!=None or (time.time()-t > 0.2): break time.sleep(1) print "[DEBUG] Device connected..." sys.stdout.flush() duration = time.time() - t print "[DEBUG] waited %f seconds on emulator to get ready" % duration if duration > 0.15: print "[INFO] Waiting for the Android Emulator to become available" time.sleep(10) # give it a little more time to get installed def create_avd(self,avd_id,avd_skin): name = "titanium_%s_%s" % (avd_id,avd_skin) if not os.path.exists(self.home_dir): os.makedirs(self.home_dir) sdcard = os.path.abspath(os.path.join(self.home_dir,'android.sdcard')) if not os.path.exists(sdcard): print "[INFO] Created shared 10M SD card for use in Android emulator(s)" run.run([self.sdk.get_mksdcard(), '10M', sdcard]) avd_path = os.path.join(self.android_home_dir, 'avd') my_avd = os.path.join(avd_path,"%s.avd" % name) if not os.path.exists(my_avd): print "[INFO] creating new AVD %s %s" % (avd_id,avd_skin) inputgen = os.path.join(template_dir,'input.py') pipe([sys.executable, inputgen], [self.sdk.get_android(), '--verbose', 'create', 'avd', '--name', name, '--target', avd_id, '-s', avd_skin, '--force', '--sdcard', sdcard]) inifile = os.path.join(my_avd,'config.ini') inifilec = open(inifile,'r').read() inifiledata = open(inifile,'w') inifiledata.write(inifilec) inifiledata.write("hw.camera=yes\n") inifiledata.close() return name def run_emulator(self,avd_id,avd_skin): print "[INFO] Launching Android emulator...one moment" print "[DEBUG] From: " + self.sdk.get_emulator() print "[DEBUG] SDCard: " + self.sdcard print "[DEBUG] AVD ID: " + avd_id print "[DEBUG] AVD Skin: " + avd_skin print "[DEBUG] SDK: " + sdk_dir # flush before a long IO operation sys.stdout.flush() # this will create an AVD on demand or re-use existing one if already created avd_name = self.create_avd(avd_id,avd_skin) sys.stdout.flush() # start the emulator p = subprocess.Popen([ self.sdk.get_emulator(), '-avd', avd_name, '-port', '5560', '-sdcard', self.sdcard, '-logcat', "'*:d *'" ]) def handler(signum, frame): print "[DEBUG] signal caught: %d" % signum if not p == None: print "[DEBUG] calling emulator kill on %d" % p.pid os.system("kill -9 %d" % p.pid) if platform.system() != "Windows": signal.signal(signal.SIGHUP, handler) signal.signal(signal.SIGQUIT, handler) signal.signal(signal.SIGINT, handler) signal.signal(signal.SIGABRT, handler) signal.signal(signal.SIGTERM, handler) # give it some time to exit prematurely time.sleep(1) rc = p.poll() if rc != None: handler(3,None) sys.exit(rc) # wait for the emulator to finish try: rc = p.wait() except OSError: handler(3,None) print "[INFO] Android Emulator has exited" sys.exit(rc) def build_and_run(self, install, avd_id, keystore=None, keystore_pass='******', keystore_alias='tidev', dist_dir=None): deploy_type = 'development' if install: if keystore == None: deploy_type = 'test' else: deploy_type = 'production' aapt = self.sdk.get_aapt() android_jar = self.sdk.get_android_jar() titanium_jar = os.path.join(self.support_dir,'titanium.jar') dx = self.sdk.get_dx() apkbuilder = self.sdk.get_apkbuilder() if keystore==None: keystore = os.path.join(self.support_dir,'dev_keystore') curdir = os.getcwd() android_jars = glob.glob(os.path.join(self.support_dir, '*.jar')) timapjar = os.path.join(self.support_dir, 'modules', 'titanium-map.jar') ti_resources_dir = os.path.join(self.support_dir, 'resources') try: os.chdir(self.project_dir) if os.path.exists('bin'): shutil.rmtree('bin') os.makedirs('bin') if os.path.exists('lib'): for jar in android_jars: shutil.copy(jar, 'lib') resources_dir = os.path.join(self.top_dir,'Resources') assets_dir = os.path.join(self.project_dir,'bin','assets') asset_resource_dir = os.path.join(assets_dir,'Resources') if not os.path.exists(assets_dir): os.makedirs(assets_dir) shutil.copy(os.path.join(self.top_dir,'tiapp.xml'), assets_dir) finalxml = os.path.join(assets_dir,'tiapp.xml') tiapp = TiAppXML(finalxml) tiapp.setDeployType(deploy_type) # we re-run the create each time through in case any of our key files # have changed android = Android(self.name,self.app_id,self.sdk) android.create(os.path.abspath(os.path.join(self.top_dir,'..')),True) # transform resources def strip_slash(s): if s[0:1]=='/' or s[0:1]=='\\': return s[1:] return s def recursive_cp(dir,dest): for root, dirs, files in os.walk(dir): # Remove file from the list of files copied # that shouldn't appear in the binaries for name in ignoreFiles: if name in files: files.remove(name); for name in ignoreDirs: if name in dirs: dirs.remove(name) # Copy remaining files relative = strip_slash(root.replace(dir,'')) relative_dest = os.path.join(dest,relative) if not os.path.exists(relative_dest): os.makedirs(relative_dest) for f in files: fullpath = os.path.join(root,f) relativedest = os.path.join(dest,relative,f) print "[TRACE] COPYING: %s => %s" %(fullpath,relativedest) shutil.copy(fullpath,relativedest) if os.path.exists(asset_resource_dir): shutil.rmtree(asset_resource_dir) os.makedirs(asset_resource_dir) recursive_cp(resources_dir,asset_resource_dir) if os.path.exists(os.path.join(asset_resource_dir,'iphone')): shutil.rmtree(os.path.join(asset_resource_dir,'iphone')) if os.path.exists(os.path.join(resources_dir,'android')): recursive_cp(os.path.join(resources_dir,'android'),asset_resource_dir) shutil.rmtree(os.path.join(asset_resource_dir,'android')) sys.stdout.flush() if not os.path.exists(assets_dir): os.makedirs(assets_dir) my_avd = None google_apis_supported = False # find the AVD we've selected and determine if we support Google APIs for avd_props in avd.get_avds(self.sdk): if avd_props['id'] == avd_id: my_avd = avd_props google_apis_supported = (my_avd['name'].find('Google')!=-1) break # compile resources full_resource_dir = os.path.join(self.project_dir,asset_resource_dir) compiler = Compiler(self.app_id,full_resource_dir,False) compiler.compile() # Android SDK version --- FIXME: this is hardcoded until i hook in Nolan's code from Developer android_sdk_version = '4' # NOTE: these are built-in permissions we need -- we probably need to refine when these are needed too permissions_required = ['INTERNET','ACCESS_WIFI_STATE','ACCESS_NETWORK_STATE', 'WRITE_EXTERNAL_STORAGE'] GEO_PERMISSION = [ 'ACCESS_COARSE_LOCATION', 'ACCESS_FINE_LOCATION', 'ACCESS_MOCK_LOCATION'] CONTACTS_PERMISSION = ['READ_CONTACTS'] VIBRATE_PERMISSION = ['VIBRATE'] CAMERA_PERMISSION = ['CAMERA'] # this is our module method to permission(s) trigger - for each method on the left, require the permission(s) on the right permission_mapping = { # GEO 'Geolocation.watchPosition' : GEO_PERMISSION, 'Geolocation.getCurrentPosition' : GEO_PERMISSION, 'Geolocation.watchHeading' : GEO_PERMISSION, 'Geolocation.getCurrentHeading' : GEO_PERMISSION, # MEDIA 'Media.vibrate' : VIBRATE_PERMISSION, 'Media.createVideoPlayer' : CAMERA_PERMISSION, 'Media.showCamera' : CAMERA_PERMISSION, # CONTACTS 'Contacts.createContact' : CONTACTS_PERMISSION, 'Contacts.saveContact' : CONTACTS_PERMISSION, 'Contacts.removeContact' : CONTACTS_PERMISSION, 'Contacts.addContact' : CONTACTS_PERMISSION, 'Contacts.getAllContacts' : CONTACTS_PERMISSION, 'Contacts.showContactPicker' : CONTACTS_PERMISSION, } VIDEO_ACTIVITY = """<activity android:name="ti.modules.titanium.media.TiVideoActivity" android:configChanges="keyboardHidden|orientation" android:launchMode="singleTask" />""" MAP_ACTIVITY = """<activity android:name="ti.modules.titanium.map.TiMapActivity" android:configChanges="keyboardHidden|orientation" android:launchMode="singleTask" /> <uses-library android:name="com.google.android.maps" />""" FACEBOOK_ACTIVITY = """<activity android:name="org.appcelerator.titanium.module.facebook.FBActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar" />""" activity_mapping = { # MEDIA 'Media.createVideoPlayer' : VIDEO_ACTIVITY, # MAPS 'Map.createView' : MAP_ACTIVITY, # FACEBOOK 'Facebook.setup' : FACEBOOK_ACTIVITY, 'Facebook.login' : FACEBOOK_ACTIVITY, 'Facebook.createLoginButton' : FACEBOOK_ACTIVITY, } # this is a map of our APIs to ones that require Google APIs to be available on the device google_apis = { "Map.createView" : True } activities = [] # figure out which permissions we need based on the used module methods for mn in compiler.module_methods: try: perms = permission_mapping[mn] if perms: for perm in perms: try: permissions_required.index(perm) except: permissions_required.append(perm) except: pass try: mappings = activity_mapping[mn] try: if google_apis[mn] and not google_apis_supported: print "[WARN] Google APIs detected but a device has been selected that doesn't support them. The API call to Titanium.%s will fail using '%s'" % (mn,my_avd['name']) sys.stdout.flush() continue except: pass try: activities.index(mappings) except: activities.append(mappings) except: pass # build the permissions XML based on the permissions detected permissions_required_xml = "" for p in permissions_required: permissions_required_xml+="<uses-permission android:name=\"android.permission.%s\"/>\n\t" % p use_maps = False # copy any module image directories for module in compiler.modules: if module.lower() == 'map' and google_apis_supported: use_maps = True print "[INFO] Detected Google Maps dependency. Using Titanium + Maps" img_dir = os.path.abspath(os.path.join(template_dir,'modules',module.lower(),'images')) if os.path.exists(img_dir): dest_img_dir = os.path.join(full_resource_dir,'modules',module.lower(),'images') if os.path.exists(dest_img_dir): shutil.rmtree(dest_img_dir) os.makedirs(dest_img_dir) copy_resources(img_dir,dest_img_dir) iconname = tiapp.properties['icon'] iconpath = os.path.join(asset_resource_dir,iconname) iconext = os.path.splitext(iconpath)[1] if not os.path.exists(os.path.join('res','drawable')): os.makedirs(os.path.join('res','drawable')) existingicon = os.path.join('res','drawable','appicon%s' % iconext) if os.path.exists(existingicon): os.remove(existingicon) if os.path.exists(iconpath): shutil.copy(iconpath,existingicon) else: shutil.copy(os.path.join(ti_resources_dir, 'default.png'), existingicon) # make our Titanium theme for our icon resfiledir = os.path.join('res','values') if not os.path.exists(resfiledir): os.makedirs(resfiledir) resfilepath = os.path.join(resfiledir,'theme.xml') if not os.path.exists(resfilepath): resfile = open(resfilepath,'w') TITANIUM_THEME="""<?xml version="1.0" encoding="utf-8"?> <resources> <style name="Theme.Titanium" parent="android:Theme"> <item name="android:windowBackground">@drawable/background</item> </style> </resources> """ resfile.write(TITANIUM_THEME) resfile.close() # create our background image which acts as splash screen during load splashimage = os.path.join(asset_resource_dir,'default.png') background_png = os.path.join('res','drawable','background.png') if os.path.exists(splashimage): print "[DEBUG] found splash screen at %s" % os.path.abspath(splashimage) shutil.copy(splashimage, background_png) else: shutil.copy(os.path.join(ti_resources_dir, 'default.png'), background_png) src_dir = os.path.join(self.project_dir, 'src') android_manifest = os.path.join(self.project_dir, 'AndroidManifest.xml') android_manifest_to_read = android_manifest # NOTE: allow the user to use their own custom AndroidManifest if they put a file named # AndroidManifest.custom.xml in their android project directory in which case all bets are # off android_custom_manifest = os.path.join(self.project_dir, 'AndroidManifest.custom.xml') if os.path.exists(android_custom_manifest): android_manifest_to_read = android_custom_manifest print "[INFO] Detected custom ApplicationManifest.xml -- no Titanium version migration supported" # we need to write out the new manifest manifest_contents = open(android_manifest_to_read,'r').read() manifest_contents = manifest_contents.replace('<!-- TI_ACTIVITIES -->',"\n\n\t\t".join(activities)) manifest_contents = manifest_contents.replace('<!-- TI_PERMISSIONS -->',permissions_required_xml) manifest_contents = manifest_contents.replace('<uses-sdk android:minSdkVersion="4" />', '<uses-sdk android:minSdkVersion="%s" />' % android_sdk_version) # write out the new manifest amf = open(android_manifest,'w') amf.write(manifest_contents) amf.close() res_dir = os.path.join(self.project_dir, 'res') output = run.run([aapt, 'package', '-m', '-J', src_dir, '-M', android_manifest, '-S', res_dir, '-I', android_jar]) if output == None: sys.exit(1) success = re.findall(r'ERROR (.*)',output) if len(success) > 0: print "[ERROR] %s" % success[0] sys.exit(1) srclist = [] jarlist = [] for root, dirs, files in os.walk(os.path.join(self.project_dir,'src')): # Strip out directories we shouldn't traverse for name in ignoreDirs: if name in dirs: dirs.remove(name) if len(files) > 0: for f in files: if f in ignoreFiles : continue path = root + os.sep + f srclist.append(path) project_module_dir = os.path.join(self.top_dir,'modules','android') if os.path.exists(project_module_dir): for root, dirs, files in os.walk(project_module_dir): # Strip out directories we shouldn't traverse for name in ignoreDirs: if name in dirs: dirs.remove(name) if len(files) > 0: for f in files: path = root + os.sep + f ext = splitext(f)[-1] if ext in ('.java'): srclist.append(path) elif ext in ('.jar'): jarlist.append(path) classes_dir = os.path.join(self.project_dir, 'bin', 'classes') if not os.path.exists(classes_dir): os.makedirs(classes_dir) jarsigner = "jarsigner" javac = "javac" java = "java" if platform.system() == "Windows": if os.environ.has_key("JAVA_HOME"): home_jarsigner = os.path.join(os.environ["JAVA_HOME"], "bin", "jarsigner.exe") home_javac = os.path.join(os.environ["JAVA_HOME"], "bin", "javac.exe") home_java = os.path.join(os.environ["JAVA_HOME"], "bin", "java.exe") if os.path.exists(home_jarsigner): jarsigner = home_jarsigner if os.path.exists(home_javac): javac = home_javac if os.path.exists(home_java): java = home_java else: found = False for path in os.environ['PATH'].split(os.pathsep): if os.path.exists(os.path.join(path, 'jarsigner.exe')) and os.path.exists(os.path.join(path, 'javac.exe')): jarsigner = os.path.join(path, 'jarsigner.exe') javac = os.path.join(path, 'javac.exe') java = os.path.join(path, 'java.exe') found = True break if not found: print "[ERROR] Error locating JDK: set $JAVA_HOME or put javac and jarsigner on your $PATH" sys.exit(1) # see if the user has app data and if so, compile in the user data # such that it can be accessed automatically using Titanium.App.Properties.getString app_data_cfg = os.path.join(self.top_dir,"appdata.cfg") if os.path.exists(app_data_cfg): props = read_properties(open(app_data_cfg,"r")) module_data = '' for key in props.keys(): data = props[key] module_data+="properties.setString(\"%s\",\"%s\");\n " % (key,data) print("[DEBUG] detected user application data at = %s"% app_data_cfg) sys.stdout.flush() dtf = os.path.join(src_dir,"AppUserData.java") if os.path.exists(dtf): os.remove(dtf) ctf = open(dtf,"w") cf_template = open(os.path.join(template_dir,'templates','AppUserData.java'),'r').read() cf_template = cf_template.replace('__MODULE_BODY__',module_data) ctf.write(cf_template) ctf.close() srclist.append(dtf) classpath = android_jar + os.pathsep + titanium_jar + os.pathsep.join(jarlist) # TODO re-enable me if use_maps: classpath += os.pathsep + timapjar javac_command = [javac, '-classpath', classpath, '-d', classes_dir, '-sourcepath', src_dir] javac_command += srclist print "[DEBUG] %s" % javac_command sys.stdout.flush() out = run.run(javac_command) classes_dex = os.path.join(self.project_dir, 'bin', 'classes.dex') android_module_jars = glob.glob(os.path.join(self.support_dir, 'modules', 'titanium-*.jar')) # the dx.bat that ships with android in windows doesn't allow command line # overriding of the java heap space, so we call the jar directly if platform.system() == 'Windows': dex_args = [java, '-Xmx512M', '-Djava.ext.dirs=%s' % self.sdk.get_platform_tools_dir(), '-jar', self.sdk.get_dx_jar()] else: dex_args = [dx, '-JXmx512M'] dex_args += ['--dex', '--output='+classes_dex, classes_dir] dex_args += android_jars dex_args += android_module_jars run.run(dex_args) ap_ = os.path.join(self.project_dir, 'bin', 'app.ap_') rhino_jar = os.path.join(self.support_dir, 'js.jar') run.run([aapt, 'package', '-f', '-M', 'AndroidManifest.xml', '-A', assets_dir, '-S', 'res', '-I', android_jar, '-I', titanium_jar, '-F', ap_]) unsigned_apk = os.path.join(self.project_dir, 'bin', 'app-unsigned.apk') apk_build_cmd = [apkbuilder, unsigned_apk, '-u', '-z', ap_, '-f', classes_dex, '-rf', src_dir, '-rj', titanium_jar, '-rj', rhino_jar] for module in android_module_jars: apk_build_cmd += ['-rj', module] run.run(apk_build_cmd) if dist_dir: app_apk = os.path.join(dist_dir, project_name + '.apk') else: app_apk = os.path.join(self.project_dir, 'bin', 'app.apk') output = run.run([jarsigner, '-storepass', keystore_pass, '-keystore', keystore, '-signedjar', app_apk, unsigned_apk, keystore_alias]) success = re.findall(r'RuntimeException: (.*)',output) if len(success) > 0: print "[ERROR] %s " %success[0] sys.exit(1) # NOTE: we can't zipalign until we officially support 1.6+ # # attempt to zipalign -- this only exists in 1.6 and above so be nice # zipalign = os.path.join(self.tools_dir,'zipalign') # if platform.system() == "Windows": # zipalign+=".exe" # # if os.path.exists(zipalign): # #zipalign -v 4 source.apk destination.apk # run.run([zipalign, '-v', '4', app_apk, app_apk+'z']) # os.rename(app_apk+'z',app_apk) if dist_dir: sys.exit(0) out = subprocess.Popen([self.sdk.get_adb(),'get-state'], stderr=subprocess.PIPE, stdout=subprocess.PIPE).communicate()[0] out = str(out).strip() # try a few times as sometimes it fails waiting on boot attempts = 0 launched = False launch_failed = False while attempts < 5: try: cmd = [self.sdk.get_adb()] if install: self.wait_for_device('d') print "[INFO] Installing application on emulator" cmd += ['-d', 'install', '-r', app_apk] else: self.wait_for_device('e') print "[INFO] Installing application on device" cmd += ['-e', 'install', '-r', app_apk] if run.run(cmd)==None: launch_failed = True elif not install: launched = True break except: time.sleep(3) attempts+=1 if launched: print "[INFO] Launching application ... %s" % self.name sys.stdout.flush() run.run([self.sdk.get_adb(), '-e' , 'shell', 'am', 'start', '-a', 'android.intent.action.MAIN', '-c','android.intent.category.LAUNCHER', '-n', '%s/.%sActivity' % (self.app_id , self.classname)]) print "[INFO] Deployed %s ... Application should be running." % self.name elif launch_failed==False: print "[INFO] Application installed. Launch from drawer on Home Screen" finally: os.chdir(curdir) sys.stdout.flush()