export.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802
  1. #include "version.h"
  2. #include "export.h"
  3. #include "tools/editor/editor_settings.h"
  4. #include "tools/editor/editor_import_export.h"
  5. #include "tools/editor/editor_node.h"
  6. #include "io/zip_io.h"
  7. #include "io/marshalls.h"
  8. #include "globals.h"
  9. #include "os/file_access.h"
  10. #include "os/os.h"
  11. #include "platform/bb10/logo.h"
  12. #include "io/xml_parser.h"
  13. #define MAX_DEVICES 5
  14. class EditorExportPlatformBB10 : public EditorExportPlatform {
  15. OBJ_TYPE( EditorExportPlatformBB10,EditorExportPlatform );
  16. String custom_package;
  17. int version_code;
  18. String version_name;
  19. String package;
  20. String name;
  21. String category;
  22. String description;
  23. String author_name;
  24. String author_id;
  25. String icon;
  26. struct Device {
  27. int index;
  28. String name;
  29. String description;
  30. };
  31. Vector<Device> devices;
  32. bool devices_changed;
  33. Mutex *device_lock;
  34. Thread *device_thread;
  35. Ref<ImageTexture> logo;
  36. volatile bool quit_request;
  37. static void _device_poll_thread(void *ud);
  38. void _fix_descriptor(Vector<uint8_t>& p_manifest);
  39. protected:
  40. bool _set(const StringName& p_name, const Variant& p_value);
  41. bool _get(const StringName& p_name,Variant &r_ret) const;
  42. void _get_property_list( List<PropertyInfo> *p_list) const;
  43. public:
  44. virtual String get_name() const { return "BlackBerry 10"; }
  45. virtual ImageCompression get_image_compression() const { return IMAGE_COMPRESSION_ETC1; }
  46. virtual Ref<Texture> get_logo() const { return logo; }
  47. virtual bool poll_devices();
  48. virtual int get_device_count() const;
  49. virtual String get_device_name(int p_device) const;
  50. virtual String get_device_info(int p_device) const;
  51. virtual Error run(int p_device,int p_flags=0);
  52. virtual bool requires_password(bool p_debug) const { return !p_debug; }
  53. virtual String get_binary_extension() const { return "bar"; }
  54. virtual Error export_project(const String& p_path,bool p_debug,int p_flags=0);
  55. virtual bool can_export(String *r_error=NULL) const;
  56. EditorExportPlatformBB10();
  57. ~EditorExportPlatformBB10();
  58. };
  59. bool EditorExportPlatformBB10::_set(const StringName& p_name, const Variant& p_value) {
  60. String n=p_name;
  61. if (n=="version/code")
  62. version_code=p_value;
  63. else if (n=="version/name")
  64. version_name=p_value;
  65. else if (n=="package/unique_name")
  66. package=p_value;
  67. else if (n=="package/category")
  68. category=p_value;
  69. else if (n=="package/name")
  70. name=p_value;
  71. else if (n=="package/description")
  72. description=p_value;
  73. else if (n=="package/icon")
  74. icon=p_value;
  75. else if (n=="package/custom_template")
  76. custom_package=p_value;
  77. else if (n=="release/author")
  78. author_name=p_value;
  79. else if (n=="release/author_id")
  80. author_id=p_value;
  81. else
  82. return false;
  83. return true;
  84. }
  85. bool EditorExportPlatformBB10::_get(const StringName& p_name,Variant &r_ret) const{
  86. String n=p_name;
  87. if (n=="version/code")
  88. r_ret=version_code;
  89. else if (n=="version/name")
  90. r_ret=version_name;
  91. else if (n=="package/unique_name")
  92. r_ret=package;
  93. else if (n=="package/category")
  94. r_ret=category;
  95. else if (n=="package/name")
  96. r_ret=name;
  97. else if (n=="package/description")
  98. r_ret=description;
  99. else if (n=="package/icon")
  100. r_ret=icon;
  101. else if (n=="package/custom_template")
  102. r_ret=custom_package;
  103. else if (n=="release/author")
  104. r_ret=author_name;
  105. else if (n=="release/author_id")
  106. r_ret=author_id;
  107. else
  108. return false;
  109. return true;
  110. }
  111. void EditorExportPlatformBB10::_get_property_list( List<PropertyInfo> *p_list) const{
  112. p_list->push_back( PropertyInfo( Variant::INT, "version/code", PROPERTY_HINT_RANGE,"1,65535,1"));
  113. p_list->push_back( PropertyInfo( Variant::STRING, "version/name") );
  114. p_list->push_back( PropertyInfo( Variant::STRING, "package/unique_name") );
  115. p_list->push_back( PropertyInfo( Variant::STRING, "package/category") );
  116. p_list->push_back( PropertyInfo( Variant::STRING, "package/name") );
  117. p_list->push_back( PropertyInfo( Variant::STRING, "package/description",PROPERTY_HINT_MULTILINE_TEXT) );
  118. p_list->push_back( PropertyInfo( Variant::STRING, "package/icon",PROPERTY_HINT_FILE,"png") );
  119. p_list->push_back( PropertyInfo( Variant::STRING, "package/custom_template", PROPERTY_HINT_GLOBAL_FILE,"zip"));
  120. p_list->push_back( PropertyInfo( Variant::STRING, "release/author") );
  121. p_list->push_back( PropertyInfo( Variant::STRING, "release/author_id") );
  122. //p_list->push_back( PropertyInfo( Variant::INT, "resources/pack_mode", PROPERTY_HINT_ENUM,"Copy,Single Exec.,Pack (.pck),Bundles (Optical)"));
  123. }
  124. void EditorExportPlatformBB10::_fix_descriptor(Vector<uint8_t>& p_descriptor) {
  125. String fpath = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp_bar-settings.xml");
  126. {
  127. FileAccessRef f = FileAccess::open(fpath,FileAccess::WRITE);
  128. f->store_buffer(p_descriptor.ptr(),p_descriptor.size());
  129. }
  130. Ref<XMLParser> parser = memnew( XMLParser );
  131. Error err = parser->open(fpath);
  132. ERR_FAIL_COND(err!=OK);
  133. String txt;
  134. err = parser->read();
  135. Vector<String> depth;
  136. while(err!=ERR_FILE_EOF) {
  137. ERR_FAIL_COND(err!=OK);
  138. switch(parser->get_node_type()) {
  139. case XMLParser::NODE_NONE: {
  140. print_line("???");
  141. } break;
  142. case XMLParser::NODE_ELEMENT: {
  143. String e="<";
  144. e+=parser->get_node_name();
  145. for(int i=0;i<parser->get_attribute_count();i++) {
  146. e+=" ";
  147. e+=parser->get_attribute_name(i)+"=\"";
  148. e+=parser->get_attribute_value(i)+"\" ";
  149. }
  150. if (parser->is_empty()) {
  151. e+="/";
  152. } else {
  153. depth.push_back(parser->get_node_name());
  154. }
  155. e+=">";
  156. txt+=e;
  157. } break;
  158. case XMLParser::NODE_ELEMENT_END: {
  159. txt+="</"+parser->get_node_name()+">";
  160. if (depth.size() && depth[depth.size()-1]==parser->get_node_name()) {
  161. depth.resize(depth.size()-1);
  162. }
  163. } break;
  164. case XMLParser::NODE_TEXT: {
  165. if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="id") {
  166. txt+=package;
  167. } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="name") {
  168. String aname;
  169. if (this->name!="") {
  170. aname=this->name;
  171. } else {
  172. aname = Globals::get_singleton()->get("application/name");
  173. }
  174. if (aname=="") {
  175. aname=_MKSTR(VERSION_NAME);
  176. }
  177. txt+=aname;
  178. } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="versionNumber") {
  179. txt+=itos(version_code);
  180. } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="description") {
  181. txt+=description;
  182. } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="author") {
  183. txt+=author_name;
  184. } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="authorId") {
  185. txt+=author_id;
  186. } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="category") {
  187. txt+=category;
  188. } else {
  189. txt+=parser->get_node_data();
  190. }
  191. } break;
  192. case XMLParser::NODE_COMMENT: {
  193. txt+="<!--"+parser->get_node_name()+"-->";
  194. } break;
  195. case XMLParser::NODE_CDATA: {
  196. //ignore
  197. //print_line("cdata");
  198. } break;
  199. case XMLParser::NODE_UNKNOWN: {
  200. //ignore
  201. txt+="<"+parser->get_node_name()+">";
  202. } break;
  203. }
  204. err = parser->read();
  205. }
  206. CharString cs = txt.utf8();
  207. p_descriptor.resize(cs.length());
  208. for(int i=0;i<cs.length();i++)
  209. p_descriptor[i]=cs[i];
  210. }
  211. Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debug, int p_flags) {
  212. EditorProgress ep("export","Exporting for BlackBerry 10",104);
  213. String src_template=custom_package;
  214. if (src_template=="") {
  215. String err;
  216. src_template = find_export_template("bb10.zip", &err);
  217. if (src_template=="") {
  218. EditorNode::add_io_error(err);
  219. return ERR_FILE_NOT_FOUND;
  220. }
  221. }
  222. FileAccess *src_f=NULL;
  223. zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
  224. ep.step("Creating FileSystem for BAR",0);
  225. unzFile pkg = unzOpen2(src_template.utf8().get_data(), &io);
  226. if (!pkg) {
  227. EditorNode::add_io_error("Could not find template zip to export:\n"+src_template);
  228. return ERR_FILE_NOT_FOUND;
  229. }
  230. DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
  231. da->change_dir(EditorSettings::get_singleton()->get_settings_path());
  232. if (da->change_dir("tmp")!=OK) {
  233. da->make_dir("tmp");
  234. if (da->change_dir("tmp")!=OK)
  235. return ERR_CANT_CREATE;
  236. }
  237. if (da->change_dir("bb10_export")!=OK) {
  238. da->make_dir("bb10_export");
  239. if (da->change_dir("bb10_export")!=OK) {
  240. return ERR_CANT_CREATE;
  241. }
  242. }
  243. String bar_dir = da->get_current_dir();
  244. if (bar_dir.ends_with("/")) {
  245. bar_dir=bar_dir.substr(0,bar_dir.length()-1);
  246. }
  247. //THIS IS SUPER, SUPER DANGEROUS!!!!
  248. //CAREFUL WITH THIS CODE, MIGHT DELETE USERS HARD DRIVE OR HOME DIR
  249. //EXTRA CHECKS ARE IN PLACE EVERYWERE TO MAKE SURE NOTHING BAD HAPPENS BUT STILL....
  250. //BE SUPER CAREFUL WITH THIS PLEASE!!!
  251. //BLACKBERRY THIS IS YOUR FAULT FOR NOT MAKING A BETTER WAY!!
  252. bool berr = bar_dir.ends_with("bb10_export");
  253. if (berr) {
  254. if (da->list_dir_begin()) {
  255. EditorNode::add_io_error("Can't ensure that dir is empty:\n"+bar_dir);
  256. ERR_FAIL_COND_V(berr,FAILED);
  257. };
  258. String f = da->get_next();
  259. while (f != "") {
  260. if (f == "." || f == "..") {
  261. f = da->get_next();
  262. continue;
  263. };
  264. Error err = da->remove(bar_dir + "/" + f);
  265. if (err != OK) {
  266. EditorNode::add_io_error("Can't ensure that dir is empty:\n"+bar_dir);
  267. ERR_FAIL_COND_V(err!=OK,err);
  268. };
  269. f = da->get_next();
  270. };
  271. da->list_dir_end();
  272. } else {
  273. print_line("ARE YOU CRAZY??? THIS IS A SERIOUS BUG HERE!!!");
  274. ERR_FAIL_V(ERR_OMFG_THIS_IS_VERY_VERY_BAD);
  275. }
  276. ERR_FAIL_COND_V(!pkg, ERR_CANT_OPEN);
  277. int ret = unzGoToFirstFile(pkg);
  278. while(ret==UNZ_OK) {
  279. //get filename
  280. unz_file_info info;
  281. char fname[16384];
  282. ret = unzGetCurrentFileInfo(pkg,&info,fname,16384,NULL,0,NULL,0);
  283. String file=fname;
  284. Vector<uint8_t> data;
  285. data.resize(info.uncompressed_size);
  286. //read
  287. unzOpenCurrentFile(pkg);
  288. unzReadCurrentFile(pkg,data.ptr(),data.size());
  289. unzCloseCurrentFile(pkg);
  290. //write
  291. if (file=="bar-descriptor.xml") {
  292. _fix_descriptor(data);
  293. }
  294. if (file=="icon.png") {
  295. bool found=false;
  296. if (this->icon!="" && this->icon.ends_with(".png")) {
  297. FileAccess *f = FileAccess::open(this->icon,FileAccess::READ);
  298. if (f) {
  299. data.resize(f->get_len());
  300. f->get_buffer(data.ptr(),data.size());
  301. memdelete(f);
  302. found=true;
  303. }
  304. }
  305. if (!found) {
  306. String appicon = Globals::get_singleton()->get("application/icon");
  307. if (appicon!="" && appicon.ends_with(".png")) {
  308. FileAccess*f = FileAccess::open(appicon,FileAccess::READ);
  309. if (f) {
  310. data.resize(f->get_len());
  311. f->get_buffer(data.ptr(),data.size());
  312. memdelete(f);
  313. }
  314. }
  315. }
  316. }
  317. if (file.find("/")) {
  318. da->make_dir_recursive(file.get_base_dir());
  319. }
  320. FileAccessRef wf = FileAccess::open(bar_dir.plus_file(file),FileAccess::WRITE);
  321. wf->store_buffer(data.ptr(),data.size());
  322. ret = unzGoToNextFile(pkg);
  323. }
  324. ep.step("Adding Files..",2);
  325. FileAccess* dst = FileAccess::open(bar_dir+"/data.pck", FileAccess::WRITE);
  326. if (!dst) {
  327. EditorNode::add_io_error("Can't copy executable file to:\n "+p_path);
  328. return ERR_FILE_CANT_WRITE;
  329. }
  330. save_pack(dst, false, 1024);
  331. dst->close();
  332. memdelete(dst);
  333. ep.step("Creating BAR Package..",104);
  334. String bb_packager=EditorSettings::get_singleton()->get("blackberry/host_tools");
  335. bb_packager=bb_packager.plus_file("blackberry-nativepackager");
  336. if (OS::get_singleton()->get_name()=="Windows")
  337. bb_packager+=".bat";
  338. if (!FileAccess::exists(bb_packager)) {
  339. EditorNode::add_io_error("Can't find packager:\n"+bb_packager);
  340. return ERR_CANT_OPEN;
  341. }
  342. List<String> args;
  343. args.push_back("-package");
  344. args.push_back(p_path);
  345. if (p_debug) {
  346. String debug_token=EditorSettings::get_singleton()->get("blackberry/debug_token");
  347. if (!FileAccess::exists(debug_token)) {
  348. EditorNode::add_io_error("Debug token not found!");
  349. } else {
  350. args.push_back("-debugToken");
  351. args.push_back(debug_token);
  352. }
  353. args.push_back("-devMode");
  354. args.push_back("-configuration");
  355. args.push_back("Device-Debug");
  356. } else {
  357. args.push_back("-configuration");
  358. args.push_back("Device-Release");
  359. }
  360. args.push_back(bar_dir.plus_file("bar-descriptor.xml"));
  361. int ec;
  362. Error err = OS::get_singleton()->execute(bb_packager,args,true,NULL,NULL,&ec);
  363. if (err!=OK)
  364. return err;
  365. if (ec!=0)
  366. return ERR_CANT_CREATE;
  367. return OK;
  368. }
  369. bool EditorExportPlatformBB10::poll_devices() {
  370. bool dc=devices_changed;
  371. devices_changed=false;
  372. return dc;
  373. }
  374. int EditorExportPlatformBB10::get_device_count() const {
  375. device_lock->lock();
  376. int dc=devices.size();
  377. device_lock->unlock();
  378. return dc;
  379. }
  380. String EditorExportPlatformBB10::get_device_name(int p_device) const {
  381. ERR_FAIL_INDEX_V(p_device,devices.size(),"");
  382. device_lock->lock();
  383. String s=devices[p_device].name;
  384. device_lock->unlock();
  385. return s;
  386. }
  387. String EditorExportPlatformBB10::get_device_info(int p_device) const {
  388. ERR_FAIL_INDEX_V(p_device,devices.size(),"");
  389. device_lock->lock();
  390. String s=devices[p_device].description;
  391. device_lock->unlock();
  392. return s;
  393. }
  394. void EditorExportPlatformBB10::_device_poll_thread(void *ud) {
  395. EditorExportPlatformBB10 *ea=(EditorExportPlatformBB10 *)ud;
  396. while(!ea->quit_request) {
  397. String bb_deploy=EditorSettings::get_singleton()->get("blackberry/host_tools");
  398. bb_deploy=bb_deploy.plus_file("blackberry-deploy");
  399. bool windows = OS::get_singleton()->get_name()=="Windows";
  400. if (windows)
  401. bb_deploy+=".bat";
  402. if (FileAccess::exists(bb_deploy)) {
  403. Vector<Device> devices;
  404. for (int i=0;i<MAX_DEVICES;i++) {
  405. String host = EditorSettings::get_singleton()->get("blackberry/device_"+itos(i+1)+"/host");
  406. if (host==String())
  407. continue;
  408. String pass = EditorSettings::get_singleton()->get("blackberry/device_"+itos(i+1)+"/password");
  409. if (pass==String())
  410. continue;
  411. List<String> args;
  412. args.push_back("-listDeviceInfo");
  413. args.push_back(host);
  414. args.push_back("-password");
  415. args.push_back(pass);
  416. int ec;
  417. String dp;
  418. Error err = OS::get_singleton()->execute(bb_deploy,args,true,NULL,&dp,&ec);
  419. if (err==OK && ec==0) {
  420. Device dev;
  421. dev.index=i;
  422. String descr;
  423. Vector<String> ls=dp.split("\n");
  424. for(int i=0;i<ls.size();i++) {
  425. String l = ls[i].strip_edges();
  426. if (l.begins_with("modelfullname::")) {
  427. dev.name=l.get_slice("::",1);
  428. descr+="Model: "+dev.name+"\n";
  429. }
  430. if (l.begins_with("modelnumber::")) {
  431. String s = l.get_slice("::",1);
  432. dev.name+=" ("+s+")";
  433. descr+="Model Number: "+s+"\n";
  434. }
  435. if (l.begins_with("scmbundle::"))
  436. descr+="OS Version: "+l.get_slice("::",1)+"\n";
  437. if (l.begins_with("[n]debug_token_expiration::"))
  438. descr+="Debug Token Expires:: "+l.get_slice("::",1)+"\n";
  439. }
  440. dev.description=descr;
  441. devices.push_back(dev);
  442. }
  443. }
  444. bool changed=false;
  445. ea->device_lock->lock();
  446. if (ea->devices.size()!=devices.size()) {
  447. changed=true;
  448. } else {
  449. for(int i=0;i<ea->devices.size();i++) {
  450. if (ea->devices[i].index!=devices[i].index) {
  451. changed=true;
  452. break;
  453. }
  454. }
  455. }
  456. if (changed) {
  457. ea->devices=devices;
  458. ea->devices_changed=true;
  459. }
  460. ea->device_lock->unlock();
  461. }
  462. uint64_t wait = 3000000;
  463. uint64_t time = OS::get_singleton()->get_ticks_usec();
  464. while(OS::get_singleton()->get_ticks_usec() - time < wait ) {
  465. OS::get_singleton()->delay_usec(1000);
  466. if (ea->quit_request)
  467. break;
  468. }
  469. }
  470. }
  471. Error EditorExportPlatformBB10::run(int p_device, int p_flags) {
  472. ERR_FAIL_INDEX_V(p_device,devices.size(),ERR_INVALID_PARAMETER);
  473. String bb_deploy=EditorSettings::get_singleton()->get("blackberry/host_tools");
  474. bb_deploy=bb_deploy.plus_file("blackberry-deploy");
  475. if (OS::get_singleton()->get_name()=="Windows")
  476. bb_deploy+=".bat";
  477. if (!FileAccess::exists(bb_deploy)) {
  478. EditorNode::add_io_error("Blackberry Deploy not found:\n"+bb_deploy);
  479. return ERR_FILE_NOT_FOUND;
  480. }
  481. device_lock->lock();
  482. EditorProgress ep("run","Running on "+devices[p_device].name,3);
  483. //export_temp
  484. ep.step("Exporting APK",0);
  485. String export_to=EditorSettings::get_singleton()->get_settings_path().plus_file("/tmp/tmpexport.bar");
  486. Error err = export_project(export_to,true,p_flags);
  487. if (err) {
  488. device_lock->unlock();
  489. return err;
  490. }
  491. #if 0
  492. ep.step("Uninstalling..",1);
  493. print_line("Uninstalling previous version: "+devices[p_device].name);
  494. List<String> args;
  495. args.push_back("-s");
  496. args.push_back(devices[p_device].id);
  497. args.push_back("uninstall");
  498. args.push_back(package);
  499. int rv;
  500. err = OS::get_singleton()->execute(adb,args,true,NULL,NULL,&rv);
  501. if (err || rv!=0) {
  502. EditorNode::add_io_error("Could not install to device.");
  503. device_lock->unlock();
  504. return ERR_CANT_CREATE;
  505. }
  506. print_line("Installing into device (please wait..): "+devices[p_device].name);
  507. #endif
  508. ep.step("Installing to Device (please wait..)..",2);
  509. List<String> args;
  510. args.clear();
  511. args.push_back("-installApp");
  512. args.push_back("-launchApp");
  513. args.push_back("-device");
  514. int idx = devices[p_device].index;
  515. String host = EditorSettings::get_singleton()->get("blackberry/device_"+itos(p_device+1)+"/host");
  516. String pass = EditorSettings::get_singleton()->get("blackberry/device_"+itos(p_device+1)+"/password");
  517. args.push_back(host);
  518. args.push_back("-password");
  519. args.push_back(pass);
  520. args.push_back(export_to);
  521. int rv;
  522. err = OS::get_singleton()->execute(bb_deploy,args,true,NULL,NULL,&rv);
  523. if (err || rv!=0) {
  524. EditorNode::add_io_error("Could not install to device.");
  525. device_lock->unlock();
  526. return ERR_CANT_CREATE;
  527. }
  528. device_lock->unlock();
  529. return OK;
  530. }
  531. EditorExportPlatformBB10::EditorExportPlatformBB10() {
  532. version_code=1;
  533. version_name="1.0";
  534. package="com.godot.noname";
  535. category="core.games";
  536. name="";
  537. author_name="Cert. Name";
  538. author_id="Cert. ID";
  539. description="Game made with Godot Engine";
  540. device_lock = Mutex::create();
  541. quit_request=false;
  542. device_thread=Thread::create(_device_poll_thread,this);
  543. devices_changed=true;
  544. Image img( _bb10_logo );
  545. logo = Ref<ImageTexture>( memnew( ImageTexture ));
  546. logo->create_from_image(img);
  547. }
  548. bool EditorExportPlatformBB10::can_export(String *r_error) const {
  549. bool valid=true;
  550. String bb_deploy=EditorSettings::get_singleton()->get("blackberry/host_tools");
  551. String err;
  552. if (!FileAccess::exists(bb_deploy.plus_file("blackberry-deploy"))) {
  553. valid=false;
  554. err+="Blackberry host tools not configured in editor settings.\n";
  555. }
  556. if (!exists_export_template("bb10.zip")) {
  557. valid=false;
  558. err+="No export template found.\nDownload and install export templates.\n";
  559. }
  560. String debug_token=EditorSettings::get_singleton()->get("blackberry/debug_token");
  561. if (!FileAccess::exists(debug_token)) {
  562. valid=false;
  563. err+="No debug token set, will not be able to test on device.\n";
  564. }
  565. if (custom_package!="" && !FileAccess::exists(custom_package)) {
  566. valid=false;
  567. err+="Custom release package not found.\n";
  568. }
  569. if (r_error)
  570. *r_error=err;
  571. return valid;
  572. }
  573. EditorExportPlatformBB10::~EditorExportPlatformBB10() {
  574. quit_request=true;
  575. Thread::wait_to_finish(device_thread);
  576. memdelete(device_lock);
  577. memdelete(device_thread);
  578. }
  579. void register_bb10_exporter() {
  580. EDITOR_DEF("blackberry/host_tools","");
  581. EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"blackberry/host_tools",PROPERTY_HINT_GLOBAL_DIR));
  582. EDITOR_DEF("blackberry/debug_token","");
  583. EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"blackberry/debug_token",PROPERTY_HINT_GLOBAL_FILE,"bar"));
  584. EDITOR_DEF("blackberry/device_1/host","");
  585. EDITOR_DEF("blackberry/device_1/password","");
  586. EDITOR_DEF("blackberry/device_2/host","");
  587. EDITOR_DEF("blackberry/device_2/password","");
  588. EDITOR_DEF("blackberry/device_3/host","");
  589. EDITOR_DEF("blackberry/device_3/password","");
  590. EDITOR_DEF("blackberry/device_4/host","");
  591. EDITOR_DEF("blackberry/device_4/password","");
  592. EDITOR_DEF("blackberry/device_5/host","");
  593. EDITOR_DEF("blackberry/device_5/password","");
  594. Ref<EditorExportPlatformBB10> exporter = Ref<EditorExportPlatformBB10>( memnew(EditorExportPlatformBB10) );
  595. EditorImportExport::get_singleton()->add_export_platform(exporter);
  596. }