summaryrefslogtreecommitdiff
path: root/platform/bb10/export/export.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/bb10/export/export.cpp')
-rw-r--r--platform/bb10/export/export.cpp805
1 files changed, 805 insertions, 0 deletions
diff --git a/platform/bb10/export/export.cpp b/platform/bb10/export/export.cpp
new file mode 100644
index 0000000000..0a19e71f08
--- /dev/null
+++ b/platform/bb10/export/export.cpp
@@ -0,0 +1,805 @@
+#include "version.h"
+#include "export.h"
+#include "tools/editor/editor_settings.h"
+#include "tools/editor/editor_import_export.h"
+#include "tools/editor/editor_node.h"
+#include "io/zip_io.h"
+#include "io/marshalls.h"
+#include "globals.h"
+#include "os/file_access.h"
+#include "os/os.h"
+#include "platform/bb10/logo.h"
+#include "io/xml_parser.h"
+
+#define MAX_DEVICES 5
+
+class EditorExportPlatformBB10 : public EditorExportPlatform {
+
+ OBJ_TYPE( EditorExportPlatformBB10,EditorExportPlatform );
+
+ String custom_package;
+
+ int version_code;
+ String version_name;
+ String package;
+ String name;
+ String category;
+ String description;
+ String author_name;
+ String author_id;
+ String icon;
+
+
+
+ struct Device {
+
+ int index;
+ String name;
+ String description;
+ };
+
+ Vector<Device> devices;
+ bool devices_changed;
+ Mutex *device_lock;
+ Thread *device_thread;
+ Ref<ImageTexture> logo;
+
+ volatile bool quit_request;
+
+
+ static void _device_poll_thread(void *ud);
+
+ void _fix_descriptor(Vector<uint8_t>& p_manifest);
+protected:
+
+ bool _set(const StringName& p_name, const Variant& p_value);
+ bool _get(const StringName& p_name,Variant &r_ret) const;
+ void _get_property_list( List<PropertyInfo> *p_list) const;
+
+public:
+
+ virtual String get_name() const { return "BlackBerry 10"; }
+ virtual ImageCompression get_image_compression() const { return IMAGE_COMPRESSION_ETC1; }
+ virtual Ref<Texture> get_logo() const { return logo; }
+
+
+ virtual bool poll_devices();
+ virtual int get_device_count() const;
+ virtual String get_device_name(int p_device) const;
+ virtual String get_device_info(int p_device) const;
+ virtual Error run(int p_device);
+
+ virtual bool requieres_password(bool p_debug) const { return !p_debug; }
+ virtual String get_binary_extension() const { return "bar"; }
+ virtual Error export_project(const String& p_path,bool p_debug,const String& p_password="");
+
+ virtual bool can_export(String *r_error=NULL) const;
+
+ EditorExportPlatformBB10();
+ ~EditorExportPlatformBB10();
+};
+
+bool EditorExportPlatformBB10::_set(const StringName& p_name, const Variant& p_value) {
+
+ String n=p_name;
+
+ if (n=="version/code")
+ version_code=p_value;
+ else if (n=="version/name")
+ version_name=p_value;
+ else if (n=="package/unique_name")
+ package=p_value;
+ else if (n=="package/category")
+ category=p_value;
+ else if (n=="package/name")
+ name=p_value;
+ else if (n=="package/description")
+ description=p_value;
+ else if (n=="package/icon")
+ icon=p_value;
+ else if (n=="package/custom_template")
+ custom_package=p_value;
+ else if (n=="release/author")
+ author_name=p_value;
+ else if (n=="release/author_id")
+ author_id=p_value;
+ else
+ return false;
+
+ return true;
+}
+
+bool EditorExportPlatformBB10::_get(const StringName& p_name,Variant &r_ret) const{
+
+ String n=p_name;
+
+ if (n=="version/code")
+ r_ret=version_code;
+ else if (n=="version/name")
+ r_ret=version_name;
+ else if (n=="package/unique_name")
+ r_ret=package;
+ else if (n=="package/category")
+ r_ret=category;
+ else if (n=="package/name")
+ r_ret=name;
+ else if (n=="package/description")
+ r_ret=description;
+ else if (n=="package/icon")
+ r_ret=icon;
+ else if (n=="package/custom_template")
+ r_ret=custom_package;
+ else if (n=="release/author")
+ r_ret=author_name;
+ else if (n=="release/author_id")
+ r_ret=author_id;
+ else
+ return false;
+
+ return true;
+}
+void EditorExportPlatformBB10::_get_property_list( List<PropertyInfo> *p_list) const{
+
+ p_list->push_back( PropertyInfo( Variant::INT, "version/code", PROPERTY_HINT_RANGE,"1,65535,1"));
+ p_list->push_back( PropertyInfo( Variant::STRING, "version/name") );
+ p_list->push_back( PropertyInfo( Variant::STRING, "package/unique_name") );
+ p_list->push_back( PropertyInfo( Variant::STRING, "package/category") );
+ p_list->push_back( PropertyInfo( Variant::STRING, "package/name") );
+ p_list->push_back( PropertyInfo( Variant::STRING, "package/description",PROPERTY_HINT_MULTILINE_TEXT) );
+ p_list->push_back( PropertyInfo( Variant::STRING, "package/icon",PROPERTY_HINT_FILE,"png") );
+ p_list->push_back( PropertyInfo( Variant::STRING, "package/custom_template", PROPERTY_HINT_FILE,"zip"));
+ p_list->push_back( PropertyInfo( Variant::STRING, "release/author") );
+ p_list->push_back( PropertyInfo( Variant::STRING, "release/author_id") );
+
+ //p_list->push_back( PropertyInfo( Variant::INT, "resources/pack_mode", PROPERTY_HINT_ENUM,"Copy,Single Exec.,Pack (.pck),Bundles (Optical)"));
+
+}
+
+void EditorExportPlatformBB10::_fix_descriptor(Vector<uint8_t>& p_descriptor) {
+
+ String fpath = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp_bar-settings.xml");
+ {
+ FileAccessRef f = FileAccess::open(fpath,FileAccess::WRITE);
+ f->store_buffer(p_descriptor.ptr(),p_descriptor.size());
+ }
+
+ Ref<XMLParser> parser = memnew( XMLParser );
+ Error err = parser->open(fpath);
+ ERR_FAIL_COND(err!=OK);
+
+ String txt;
+ err = parser->read();
+ Vector<String> depth;
+
+ while(err!=ERR_FILE_EOF) {
+
+ ERR_FAIL_COND(err!=OK);
+
+ switch(parser->get_node_type()) {
+
+ case XMLParser::NODE_NONE: {
+ print_line("???");
+ } break;
+ case XMLParser::NODE_ELEMENT: {
+ String e="<";
+ e+=parser->get_node_name();
+ for(int i=0;i<parser->get_attribute_count();i++) {
+ e+=" ";
+ e+=parser->get_attribute_name(i)+"=\"";
+ e+=parser->get_attribute_value(i)+"\" ";
+ }
+
+
+
+ if (parser->is_empty()) {
+ e+="/";
+ } else {
+ depth.push_back(parser->get_node_name());
+ }
+
+ e+=">";
+ txt+=e;
+
+ } break;
+ case XMLParser::NODE_ELEMENT_END: {
+
+ txt+="</"+parser->get_node_name()+">";
+ if (depth.size() && depth[depth.size()-1]==parser->get_node_name()) {
+ depth.resize(depth.size()-1);
+ }
+
+
+ } break;
+ case XMLParser::NODE_TEXT: {
+ if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="id") {
+
+ txt+=package;
+ } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="name") {
+
+ String aname;
+ if (this->name!="") {
+ aname=this->name;
+ } else {
+ aname = Globals::get_singleton()->get("application/name");
+
+ }
+
+ if (aname=="") {
+ aname=_MKSTR(VERSION_NAME);
+ }
+
+ txt+=aname;
+
+ } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="versionNumber") {
+ txt+=itos(version_code);
+ } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="description") {
+ txt+=description;
+ } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="author") {
+ txt+=author_name;
+ } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="authorId") {
+ txt+=author_id;
+ } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="category") {
+ txt+=category;
+ } else {
+ txt+=parser->get_node_data();
+ }
+ } break;
+ case XMLParser::NODE_COMMENT: {
+ txt+="<!--"+parser->get_node_name()+"-->";
+ } break;
+ case XMLParser::NODE_CDATA: {
+ //ignore
+ //print_line("cdata");
+ } break;
+ case XMLParser::NODE_UNKNOWN: {
+ //ignore
+ txt+="<"+parser->get_node_name()+">";
+ } break;
+ }
+
+ err = parser->read();
+ }
+
+
+ CharString cs = txt.utf8();
+ p_descriptor.resize(cs.length());
+ for(int i=0;i<cs.length();i++)
+ p_descriptor[i]=cs[i];
+
+}
+
+
+
+Error EditorExportPlatformBB10::export_project(const String& p_path,bool p_debug,const String& p_password) {
+
+
+ EditorProgress ep("export","Exporting for BlackBerry 10",104);
+
+ String template_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/";
+
+ String src_template=custom_package!=""?custom_package:template_path.plus_file("bb10.zip");
+
+
+ FileAccess *src_f=NULL;
+ zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
+
+ ep.step("Creating FileSystem for BAR",0);
+
+ unzFile pkg = unzOpen2(src_template.utf8().get_data(), &io);
+ if (!pkg) {
+
+ EditorNode::add_io_error("Could not find template zip to export:\n"+src_template);
+ return ERR_FILE_NOT_FOUND;
+ }
+
+ DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ da->change_dir(EditorSettings::get_singleton()->get_settings_path());
+
+
+ if (da->change_dir("tmp")!=OK) {
+ da->make_dir("tmp");
+ if (da->change_dir("tmp")!=OK)
+ return ERR_CANT_CREATE;
+ }
+
+ if (da->change_dir("bb10_export")!=OK) {
+ da->make_dir("bb10_export");
+ if (da->change_dir("bb10_export")!=OK) {
+ return ERR_CANT_CREATE;
+ }
+ }
+
+
+ String bar_dir = da->get_current_dir();
+ if (bar_dir.ends_with("/")) {
+ bar_dir=bar_dir.substr(0,bar_dir.length()-1);
+ }
+
+ //THIS IS SUPER, SUPER DANGEROUS!!!!
+ //CAREFUL WITH THIS CODE, MIGHT DELETE USERS HARD DRIVE OR HOME DIR
+ //EXTRA CHECKS ARE IN PLACE EVERYWERE TO MAKE SURE NOTHING BAD HAPPENS BUT STILL....
+ //BE SUPER CAREFUL WITH THIS PLEASE!!!
+ //BLACKBERRY THIS IS YOUR FAULT FOR NOT MAKING A BETTER WAY!!
+
+ if (bar_dir.ends_with("bb10_export")) {
+ Error err = da->erase_contents_recursive();
+ if (err!=OK) {
+ EditorNode::add_io_error("Can't ensure that dir is empty:\n"+bar_dir);
+ ERR_FAIL_COND_V(err!=OK,err);
+ }
+
+ } else {
+ print_line("ARE YOU CRAZY??? THIS IS A SERIOUS BUG HERE!!!");
+ ERR_FAIL_V(ERR_OMFG_THIS_IS_VERY_VERY_BAD);
+ }
+
+
+ ERR_FAIL_COND_V(!pkg, ERR_CANT_OPEN);
+ int ret = unzGoToFirstFile(pkg);
+
+
+
+ while(ret==UNZ_OK) {
+
+ //get filename
+ unz_file_info info;
+ char fname[16384];
+ ret = unzGetCurrentFileInfo(pkg,&info,fname,16384,NULL,0,NULL,0);
+
+ String file=fname;
+
+ Vector<uint8_t> data;
+ data.resize(info.uncompressed_size);
+
+ //read
+ unzOpenCurrentFile(pkg);
+ unzReadCurrentFile(pkg,data.ptr(),data.size());
+ unzCloseCurrentFile(pkg);
+
+ //write
+
+ if (file=="bar-descriptor.xml") {
+
+ _fix_descriptor(data);
+ }
+
+ if (file=="icon.png") {
+ bool found=false;
+
+ if (this->icon!="" && this->icon.ends_with(".png")) {
+
+ FileAccess *f = FileAccess::open(this->icon,FileAccess::READ);
+ if (f) {
+
+ data.resize(f->get_len());
+ f->get_buffer(data.ptr(),data.size());
+ memdelete(f);
+ found=true;
+ }
+
+ }
+
+ if (!found) {
+
+ String appicon = Globals::get_singleton()->get("application/icon");
+ if (appicon!="" && appicon.ends_with(".png")) {
+ FileAccess*f = FileAccess::open(appicon,FileAccess::READ);
+ if (f) {
+ data.resize(f->get_len());
+ f->get_buffer(data.ptr(),data.size());
+ memdelete(f);
+ }
+ }
+ }
+ }
+
+
+ if (file.find("/")) {
+
+ da->make_dir_recursive(file.get_base_dir());
+ }
+
+ FileAccessRef wf = FileAccess::open(bar_dir.plus_file(file),FileAccess::WRITE);
+ wf->store_buffer(data.ptr(),data.size());
+
+ ret = unzGoToNextFile(pkg);
+ }
+
+ ep.step("Finding Files..",1);
+
+ Vector<StringName> files=get_dependencies(false);
+
+ ep.step("Adding Files..",2);
+
+ da->change_dir(bar_dir);
+ da->make_dir("assets");
+ Error err = da->change_dir("assets");
+ ERR_FAIL_COND_V(err,err);
+
+ String asset_dir=da->get_current_dir();
+ if (!asset_dir.ends_with("/"))
+ asset_dir+="/";
+
+ for(int i=0;i<files.size();i++) {
+
+ String fname=files[i];
+ Vector<uint8_t> data = get_exported_file(fname);
+ /*
+ FileAccess *f=FileAccess::open(files[i],FileAccess::READ);
+ if (!f) {
+ EditorNode::add_io_error("Couldn't read: "+String(files[i]));
+ }
+ ERR_CONTINUE(!f);
+ data.resize(f->get_len());
+ f->get_buffer(data.ptr(),data.size());
+*/
+ String dst_path=fname;
+ dst_path=dst_path.replace_first("res://",asset_dir);
+
+ da->make_dir_recursive(dst_path.get_base_dir());
+
+ ep.step("Adding File: "+String(files[i]).get_file(),3+i*100/files.size());
+
+ FileAccessRef fr = FileAccess::open(dst_path,FileAccess::WRITE);
+ fr->store_buffer(data.ptr(),data.size());
+ }
+
+
+ ep.step("Creating BAR Package..",104);
+
+ String bb_packager=EditorSettings::get_singleton()->get("blackberry/host_tools");
+ bb_packager=bb_packager.plus_file("blackberry-nativepackager");
+ if (OS::get_singleton()->get_name()=="Windows")
+ bb_packager+=".exe";
+
+
+ if (!FileAccess::exists(bb_packager)) {
+ EditorNode::add_io_error("Can't find packager:\n"+bb_packager);
+ return ERR_CANT_OPEN;
+ }
+
+ List<String> args;
+ args.push_back("-package");
+ args.push_back(p_path);
+ if (p_debug) {
+
+ String debug_token=EditorSettings::get_singleton()->get("blackberry/debug_token");
+ if (!FileAccess::exists(debug_token)) {
+ EditorNode::add_io_error("Debug token not found!");
+ } else {
+ args.push_back("-debugToken");
+ args.push_back(debug_token);
+ }
+ args.push_back("-devMode");
+ args.push_back("-configuration");
+ args.push_back("Device-Debug");
+ } else {
+
+ args.push_back("-configuration");
+ args.push_back("Device-Release");
+ }
+ args.push_back(bar_dir.plus_file("bar-descriptor.xml"));
+
+ int ec;
+
+ err = OS::get_singleton()->execute(bb_packager,args,true,NULL,NULL,&ec);
+
+ if (err!=OK)
+ return err;
+ if (ec!=0)
+ return ERR_CANT_CREATE;
+
+ return OK;
+
+}
+
+
+bool EditorExportPlatformBB10::poll_devices() {
+
+ bool dc=devices_changed;
+ devices_changed=false;
+ return dc;
+}
+
+int EditorExportPlatformBB10::get_device_count() const {
+
+ device_lock->lock();
+ int dc=devices.size();
+ device_lock->unlock();
+
+ return dc;
+
+}
+String EditorExportPlatformBB10::get_device_name(int p_device) const {
+
+ ERR_FAIL_INDEX_V(p_device,devices.size(),"");
+ device_lock->lock();
+ String s=devices[p_device].name;
+ device_lock->unlock();
+ return s;
+}
+String EditorExportPlatformBB10::get_device_info(int p_device) const {
+
+ ERR_FAIL_INDEX_V(p_device,devices.size(),"");
+ device_lock->lock();
+ String s=devices[p_device].description;
+ device_lock->unlock();
+ return s;
+}
+
+void EditorExportPlatformBB10::_device_poll_thread(void *ud) {
+
+ EditorExportPlatformBB10 *ea=(EditorExportPlatformBB10 *)ud;
+
+ while(!ea->quit_request) {
+
+ String bb_deploy=EditorSettings::get_singleton()->get("blackberry/host_tools");
+ bb_deploy=bb_deploy.plus_file("blackberry-deploy");
+ bool windows = OS::get_singleton()->get_name()=="Windows";
+ if (windows)
+ bb_deploy+=".exe";
+
+ if (!FileAccess::exists(bb_deploy)) {
+ OS::get_singleton()->delay_usec(3000000);
+ continue; //adb not configured
+ }
+
+ Vector<Device> devices;
+
+
+ for (int i=0;i<MAX_DEVICES;i++) {
+
+ String host = EditorSettings::get_singleton()->get("blackberry/device_"+itos(i+1)+"/host");
+ if (host==String())
+ continue;
+ String pass = EditorSettings::get_singleton()->get("blackberry/device_"+itos(i+1)+"/password");
+ if (pass==String())
+ continue;
+
+ List<String> args;
+ args.push_back("-listDeviceInfo");
+ args.push_back(host);
+ args.push_back("-password");
+ args.push_back(pass);
+
+
+ int ec;
+ String dp;
+
+ Error err = OS::get_singleton()->execute(bb_deploy,args,true,NULL,&dp,&ec);
+
+ if (err==OK && ec==0) {
+
+ Device dev;
+ dev.index=i;
+ String descr;
+ Vector<String> ls=dp.split("\n");
+
+ for(int i=0;i<ls.size();i++) {
+
+ String l = ls[i].strip_edges();
+ if (l.begins_with("modelfullname::")) {
+ dev.name=l.get_slice("::",1);
+ descr+="Model: "+dev.name+"\n";
+ }
+ if (l.begins_with("modelnumber::")) {
+ String s = l.get_slice("::",1);
+ dev.name+=" ("+s+")";
+ descr+="Model Number: "+s+"\n";
+ }
+ if (l.begins_with("scmbundle::"))
+ descr+="OS Version: "+l.get_slice("::",1)+"\n";
+ if (l.begins_with("[n]debug_token_expiration::"))
+ descr+="Debug Token Expires:: "+l.get_slice("::",1)+"\n";
+
+ }
+
+ dev.description=descr;
+ devices.push_back(dev);
+ }
+
+ }
+
+ bool changed=false;
+
+
+ ea->device_lock->lock();
+
+ if (ea->devices.size()!=devices.size()) {
+ changed=true;
+ } else {
+
+ for(int i=0;i<ea->devices.size();i++) {
+
+ if (ea->devices[i].index!=devices[i].index) {
+ changed=true;
+ break;
+ }
+ }
+ }
+
+ if (changed) {
+
+ ea->devices=devices;
+ ea->devices_changed=true;
+ }
+
+ ea->device_lock->unlock();
+
+ OS::get_singleton()->delay_usec(3000000);
+
+ }
+
+}
+
+Error EditorExportPlatformBB10::run(int p_device) {
+
+ ERR_FAIL_INDEX_V(p_device,devices.size(),ERR_INVALID_PARAMETER);
+
+ String bb_deploy=EditorSettings::get_singleton()->get("blackberry/host_tools");
+ bb_deploy=bb_deploy.plus_file("blackberry-deploy");
+ if (OS::get_singleton()->get_name()=="Windows")
+ bb_deploy+=".exe";
+
+ if (!FileAccess::exists(bb_deploy)) {
+ EditorNode::add_io_error("Blackberry Deploy not found:\n"+bb_deploy);
+ return ERR_FILE_NOT_FOUND;
+ }
+
+
+ device_lock->lock();
+
+
+ EditorProgress ep("run","Running on "+devices[p_device].name,3);
+
+ //export_temp
+ ep.step("Exporting APK",0);
+
+ String export_to=EditorSettings::get_singleton()->get_settings_path().plus_file("/tmp/tmpexport.bar");
+ Error err = export_project(export_to,true);
+ if (err) {
+ device_lock->unlock();
+ return err;
+ }
+#if 0
+ ep.step("Uninstalling..",1);
+
+ print_line("Uninstalling previous version: "+devices[p_device].name);
+ List<String> args;
+ args.push_back("-s");
+ args.push_back(devices[p_device].id);
+ args.push_back("uninstall");
+ args.push_back(package);
+ int rv;
+ err = OS::get_singleton()->execute(adb,args,true,NULL,NULL,&rv);
+
+ if (err || rv!=0) {
+ EditorNode::add_io_error("Could not install to device.");
+ device_lock->unlock();
+ return ERR_CANT_CREATE;
+ }
+
+ print_line("Installing into device (please wait..): "+devices[p_device].name);
+
+#endif
+ ep.step("Installing to Device (please wait..)..",2);
+
+ List<String> args;
+ args.clear();
+ args.push_back("-installApp");
+ args.push_back("-launchApp");
+ args.push_back("-device");
+ int idx = devices[p_device].index;
+ String host = EditorSettings::get_singleton()->get("blackberry/device_"+itos(p_device+1)+"/host");
+ String pass = EditorSettings::get_singleton()->get("blackberry/device_"+itos(p_device+1)+"/password");
+ args.push_back(host);
+ args.push_back("-password");
+ args.push_back(pass);
+ args.push_back(export_to);
+
+ int rv;
+ err = OS::get_singleton()->execute(bb_deploy,args,true,NULL,NULL,&rv);
+ if (err || rv!=0) {
+ EditorNode::add_io_error("Could not install to device.");
+ device_lock->unlock();
+ return ERR_CANT_CREATE;
+ }
+
+ device_lock->unlock();
+ return OK;
+
+
+}
+
+
+EditorExportPlatformBB10::EditorExportPlatformBB10() {
+
+ version_code=1;
+ version_name="1.0";
+ package="com.godot.noname";
+ category="core.games";
+ name="";
+ author_name="Cert. Name";
+ author_id="Cert. ID";
+ description="Game made with Godot Engine";
+
+ device_lock = Mutex::create();
+ quit_request=false;
+
+ device_thread=Thread::create(_device_poll_thread,this);
+ devices_changed=true;
+
+ Image img( _bb10_logo );
+ logo = Ref<ImageTexture>( memnew( ImageTexture ));
+ logo->create_from_image(img);
+}
+
+bool EditorExportPlatformBB10::can_export(String *r_error) const {
+
+ bool valid=true;
+ String bb_deploy=EditorSettings::get_singleton()->get("blackberry/host_tools");
+ String err;
+
+ if (!FileAccess::exists(bb_deploy.plus_file("blackberry-deploy"))) {
+
+ valid=false;
+ err+="Blackberry host tools not configured in editor settings.\n";
+ }
+
+ String exe_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/";
+
+ if (!FileAccess::exists(exe_path+"bb10.zip")) {
+ valid=false;
+ err+="No export template found.\nDownload and install export templates.\n";
+ }
+
+ String debug_token=EditorSettings::get_singleton()->get("blackberry/debug_token");
+
+ if (!FileAccess::exists(debug_token)) {
+ valid=false;
+ err+="No debug token set, will not be able to test on device.\n";
+ }
+
+
+ if (custom_package!="" && !FileAccess::exists(custom_package)) {
+ valid=false;
+ err+="Custom release package not found.\n";
+ }
+
+ if (r_error)
+ *r_error=err;
+
+ return valid;
+}
+
+
+EditorExportPlatformBB10::~EditorExportPlatformBB10() {
+
+ quit_request=true;
+ Thread::wait_to_finish(device_thread);
+}
+
+
+void register_bb10_exporter() {
+
+ EDITOR_DEF("blackberry/host_tools","");
+ EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"blackberry/host_tools",PROPERTY_HINT_GLOBAL_DIR));
+ EDITOR_DEF("blackberry/debug_token","");
+ EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"blackberry/debug_token",PROPERTY_HINT_GLOBAL_FILE,"bar"));
+ EDITOR_DEF("blackberry/device_1/host","");
+ EDITOR_DEF("blackberry/device_1/password","");
+ EDITOR_DEF("blackberry/device_2/host","");
+ EDITOR_DEF("blackberry/device_2/password","");
+ EDITOR_DEF("blackberry/device_3/host","");
+ EDITOR_DEF("blackberry/device_3/password","");
+ EDITOR_DEF("blackberry/device_4/host","");
+ EDITOR_DEF("blackberry/device_4/password","");
+ EDITOR_DEF("blackberry/device_5/host","");
+ EDITOR_DEF("blackberry/device_5/password","");
+
+ Ref<EditorExportPlatformBB10> exporter = Ref<EditorExportPlatformBB10>( memnew(EditorExportPlatformBB10) );
+ EditorImportExport::get_singleton()->add_export_platform(exporter);
+
+
+}
+