DeviceUpdateLogic.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. #pragma once
  2. #include "uart/ProtocolSender.h"
  3. #include "manager/ConfigManager.h"
  4. #include "net/NetManager.h"
  5. #include "core/update_assistant.h"
  6. #include "edge/popup_service.h"
  7. #include "base/strings.hpp"
  8. #include "restclient-cpp/restclient.h"
  9. #include "base/http_client.h"
  10. #include "net/tcp_client.h"
  11. #include "os/UpgradeMonitor.h"
  12. #include "core/utilities.h"
  13. #include "core/jhws.h"
  14. #include "service/BusinessConfig.h"
  15. #include "manager/LanguageManager.h"
  16. namespace {
  17. base::UpdateAssistant assistant;
  18. base::VersionInfo info;
  19. enum Timer {
  20. kTimerProgress,
  21. };
  22. int loading_index = 0;
  23. }
  24. Json::Value linuxVersionList;
  25. string updateUrl;
  26. int chooseVersionId;
  27. static void getLinuxVersionList() {
  28. std::string url = getHttpGateway() + "/util/get_linux_version_list";
  29. LOGD("请求Linux设备初始化版本列表. url = %s", url.c_str());
  30. //发起HTTP GET请求
  31. RestClient::Response r = RestClient::get(url);
  32. if (r.code != 200) {
  33. LOGD("请求Linux设备初始化版本列表-> 错误代码: %d", r.code);
  34. return;
  35. }
  36. LOGD("获得Linux设备初始化版本列表. result = %s", r.body.c_str());
  37. //解析json
  38. Json::Reader reader;
  39. Json::Value root;
  40. if(reader.parse(r.body, root, false)) {
  41. linuxVersionList = root;
  42. mDeviceTypeListViewPtr->refreshListView();
  43. }
  44. }
  45. void NavibarSetProgressWindowVisible(bool visible) {
  46. mProgressWindowPtr->setVisible(visible);
  47. }
  48. void NavibarSetDialog1WindowVisible(bool visible) {
  49. mDialogWindowPtr->setVisible(visible);
  50. }
  51. void NavibarSetProgressMessage(const std::string& msg) {
  52. mProgressMessageTextViewPtr->setText(msg);
  53. }
  54. void NavibarSetDialog1Message(const std::string& msg) {
  55. mDialogTextViewPtr->setText(msg);
  56. }
  57. void NavibarProgressAnimation(bool visible) {
  58. mProgressLoadingTextViewPtr->setVisible(visible);
  59. if (visible) {
  60. loading_index = 0;
  61. mActivityPtr->registerUserTimer(kTimerProgress, 100);
  62. return;
  63. }
  64. mActivityPtr->unregisterUserTimer(kTimerProgress);
  65. }
  66. void NavibarDialog1ClickOk() {
  67. while (PopupService::instance()->busy_) {
  68. PopupService::instance()->busy_ = false;
  69. }
  70. //EASYUICONTEXT->hideNaviBar();
  71. }
  72. void updateDevice(){
  73. PopupService::Show([](PopupService* srv){
  74. base::HttpClient client;
  75. client.SetConnectionTimeout(5000);
  76. client.SetTimeout(120 * 1000);
  77. std::string url = getHttpGateway() + "/" + info.url.c_str();
  78. LOGD("请求更新文件的url: %s", url.c_str());
  79. base::HttpRequest req("GET", url, ""); // 去获取文件
  80. const char* tmp_file = "/tmp/update.img";
  81. base::HttpResponse response =
  82. client.Do(req, tmp_file, [srv, info](int64_t dltotal,
  83. int64_t dlnow, int64_t ultotal, int64_t ulnow){
  84. LOGD("downloading %lld/%lld", dlnow, dltotal);
  85. string msg = LANGUAGEMANAGER->getValue("Downloading") + " %.0f%%";
  86. srv->SetMessage(base::format(msg.c_str(),
  87. dltotal == 0 ? 0 : (dlnow * 1.0/dltotal * 100)));
  88. return 0;
  89. });
  90. if (response.StatusCode() != 200) { // 下载失败
  91. string msg = LANGUAGEMANAGER->getValue("DownloadFailed") + "%d";
  92. srv->SetMessage(base::format(msg.c_str(), response.ErrorCode()));
  93. return -1;
  94. }
  95. // TODO: 应该去判断一下,下载的版本是否真的大于当前版本号
  96. UpgradeMonitor::getInstance()->checkUpgradeFile("/mnt/extsd");
  97. LOGD("img版本-> %s", "");
  98. system("touch /tmp/zkautoupgrade");
  99. UPGRADEMONITOR->checkUpgradeFile("/tmp");
  100. // const char* msg = "-1";
  101. // TcpClient::instance()->sendMsg(msg);
  102. return 0;
  103. });
  104. }
  105. void openInitWindow() {
  106. getLinuxVersionList();
  107. chooseVersionId = 0;
  108. mInitWindowPtr->showWnd();
  109. }
  110. /**
  111. * 注册定时器
  112. * 填充数组用于注册定时器
  113. * 注意:id不能重复
  114. */
  115. static S_ACTIVITY_TIMEER REGISTER_ACTIVITY_TIMER_TAB[] = {
  116. //{0, 6000}, //定时器id=0, 时间间隔6秒
  117. //{1, 1000},
  118. };
  119. /**
  120. * 当界面构造时触发
  121. */
  122. static void onUI_init(){
  123. // mVersionPtr->setText(StoragePreferences::getString(WDKL_VERSION, GetVersion()));
  124. // int currentVersionNo = StoragePreferences::getInt(JHWS_VERSION_NUMBER, GetVersionNo());
  125. std::string currentVersion = getVersion();
  126. int currentVersionNo = getVersionNo();
  127. mVersionPtr->setText(currentVersion); // 写入界面的版本
  128. mVersionNoPtr->setText(to_string(currentVersionNo)); // 写入界面的版本号
  129. mProgressWindowPtr->setVisible(false);
  130. mDialogWindowPtr->setVisible(false);
  131. mInitWindowPtr->hideWnd();
  132. }
  133. /**
  134. * 当切换到该界面时触发
  135. */
  136. static void onUI_intent(const Intent *intentPtr) {
  137. if (intentPtr != NULL) {
  138. std::string _appUpdate = intentPtr->getExtra(appUpdate);
  139. if (_appUpdate == "true") {
  140. int ret = assistant.GetLatest("bed", &info);
  141. // int currentVersionNo = StoragePreferences::getInt(JHWS_VERSION_NUMBER, GetVersionNo());
  142. int currentVersionNo = getVersionNo();
  143. LOGD("from server : %s %d, from device: %d", info.version.c_str(), info.versionNo, currentVersionNo);
  144. if (currentVersionNo < info.versionNo) {
  145. updateDevice();
  146. }
  147. }
  148. }
  149. }
  150. /*
  151. * 当界面显示时触发
  152. */
  153. static void onUI_show() {
  154. }
  155. /*
  156. * 当界面隐藏时触发
  157. */
  158. static void onUI_hide() {
  159. }
  160. /*
  161. * 当界面完全退出时触发
  162. */
  163. static void onUI_quit() {
  164. }
  165. /**
  166. * 串口数据回调接口
  167. */
  168. static void onProtocolDataUpdate(const SProtocolData &data) {
  169. }
  170. /**
  171. * 定时器触发函数
  172. * 不建议在此函数中写耗时操作,否则将影响UI刷新
  173. * 参数: id
  174. * 当前所触发定时器的id,与注册时的id相同
  175. * 返回值: true
  176. * 继续运行当前定时器
  177. * false
  178. * 停止运行当前定时器
  179. */
  180. static bool onUI_Timer(int id){
  181. switch (id) {
  182. case kTimerProgress: {
  183. loading_index = (loading_index + 1) % 8;
  184. mProgressLoadingTextViewPtr->setBackgroundPic(
  185. base::format("loading/%d.png", loading_index).c_str());
  186. }
  187. break;
  188. default:
  189. break;
  190. }
  191. return true;
  192. }
  193. /**
  194. * 有新的触摸事件时触发
  195. * 参数:ev
  196. * 新的触摸事件
  197. * 返回值:true
  198. * 表示该触摸事件在此被拦截,系统不再将此触摸事件传递到控件上
  199. * false
  200. * 触摸事件将继续传递到控件上
  201. */
  202. static bool ondeviceUpdateActivityTouchEvent(const MotionEvent &ev) {
  203. switch (ev.mActionStatus) {
  204. case MotionEvent::E_ACTION_DOWN://触摸按下
  205. //LOGD("时刻 = %ld 坐标 x = %d, y = %d", ev.mEventTime, ev.mX, ev.mY);
  206. break;
  207. case MotionEvent::E_ACTION_MOVE://触摸滑动
  208. break;
  209. case MotionEvent::E_ACTION_UP: //触摸抬起
  210. break;
  211. default:
  212. break;
  213. }
  214. return false;
  215. }
  216. static bool onButtonClick_sys_back(ZKButton *pButton) {
  217. LOGD(" ButtonClick sys_back !!!\n");
  218. return false;
  219. }
  220. static int getListItemCount_DeviceTypeListView(const ZKListView *pListView) {
  221. //LOGD("getListItemCount_DeviceTypeListView !\n");
  222. if (linuxVersionList.size() > 4) {
  223. return linuxVersionList.size();
  224. }
  225. return 4;
  226. }
  227. static void obtainListItemData_DeviceTypeListView(ZKListView *pListView,ZKListView::ZKListItem *pListItem, int index) {
  228. //LOGD(" obtainListItemData_ DeviceTypeListView !!!\n");
  229. string version = linuxVersionList[index]["type_name"].asString() + " " + linuxVersionList[index]["version_code"].asString();
  230. if (version != " ") {
  231. pListItem->setText(version);
  232. }
  233. else {
  234. pListItem->setText("");
  235. }
  236. if (index == chooseVersionId) {
  237. updateUrl = linuxVersionList[chooseVersionId]["app_path"].asString();
  238. pListItem->setSelected(true);
  239. }
  240. else {
  241. pListItem->setSelected(false);
  242. }
  243. }
  244. static void onListItemClick_DeviceTypeListView(ZKListView *pListView, int index, int id) {
  245. //LOGD(" onListItemClick_ DeviceTypeListView !!!\n");
  246. chooseVersionId = index;
  247. updateUrl = linuxVersionList[index]["app_path"].asString();
  248. }
  249. static bool onButtonClick_BackButton(ZKButton *pButton) {
  250. LOGD(" ButtonClick BackButton !!!\n");
  251. mInitWindowPtr->hideWnd();
  252. return false;
  253. }
  254. static bool onButtonClick_FindBackButton(ZKButton *pButton) {
  255. LOGD(" ButtonClick FindBackButton !!!\n");
  256. EASYUICONTEXT->goBack();
  257. return false;
  258. }
  259. static bool onButtonClick_UpdateButton(ZKButton *pButton) {
  260. LOGD(" ButtonClick UpdateButton !!!\n");
  261. PopupService::Show([](PopupService* srv){
  262. string msg = LANGUAGEMANAGER->getValue("Searching");
  263. srv->SetMessage(msg);
  264. if (!NETMANAGER->getEthernetManager()->isConnected()) {
  265. std::string msg = LANGUAGEMANAGER->getValue("EthernetDisconnect");
  266. srv->SetMessage(msg);
  267. return -1;
  268. }
  269. int ret = assistant.GetLatest("bed", &info);
  270. if (ret != 0) {
  271. LOGE("get latest failed ret %d", ret);
  272. msg = LANGUAGEMANAGER->getValue("GetVersionFailed") + "%d";
  273. srv->SetMessage(base::format(msg.c_str(), ret));
  274. return ret;
  275. }
  276. // int currentVersionNo = StoragePreferences::getInt(JHWS_VERSION_NUMBER, GetVersionNo());
  277. int currentVersionNo = getVersionNo();
  278. // LOGD("from server : %s %d, from device: %d", info.version.c_str(), info.versionNo, currentVersionNo);
  279. LOGD("更新版本,服务器版本-> %s, 版本号-> %d, 本机版本号-> %d", info.version.c_str(), info.versionNo, currentVersionNo);
  280. if (currentVersionNo >= info.versionNo) { // 判断本身的版本大于新的版本时,不进行升级
  281. msg = LANGUAGEMANAGER->getValue("IsTheLastVersion"); // 已经是最新版本
  282. srv->SetMessage(msg);
  283. return -1;
  284. }
  285. mVersionNewPtr->setText(info.version);
  286. mVersionNoNewPtr->setText(to_string(info.versionNo));
  287. mFindWindowPtr->showWnd();
  288. return 0;
  289. });
  290. return false;
  291. }
  292. static bool onButtonClick_InitButton(ZKButton *pButton) {
  293. LOGD(" ButtonClick InitButton !!!\n");
  294. Intent* intent = new Intent();
  295. intent->putExtra(functionWindows, "init");
  296. EASYUICONTEXT->openActivity("functionActivity", intent);
  297. return false;
  298. }
  299. static bool onButtonClick_InstantlyButton(ZKButton *pButton) {
  300. LOGD(" ButtonClick InstantlyButton !!!\n");
  301. updateDevice();
  302. return false;
  303. }
  304. static bool onButtonClick_DialogButton(ZKButton *pButton) {
  305. LOGD(" ButtonClick DialogButton !!!\n");
  306. return false;
  307. }
  308. static bool onButtonClick_InitUpdateButton(ZKButton *pButton) {
  309. LOGD(" ButtonClick InitUpdateButton !!!\n");
  310. // 小于的时候,代表在linuxVersionList里面
  311. if (updateUrl != "") {
  312. mProgressWindowPtr->showWnd();
  313. PopupService::Show([](PopupService* srv){
  314. base::HttpClient client;
  315. client.SetConnectionTimeout(5000);
  316. client.SetTimeout(120 * 1000);
  317. std::string url = getHttpGateway() + "/" + updateUrl;
  318. LOGD("请求更新文件的url: %s", url.c_str());
  319. base::HttpRequest req("GET", url, ""); // 去获取文件
  320. const char* tmp_file = "/tmp/update.img";
  321. base::HttpResponse response =
  322. client.Do(req, tmp_file, [srv, info](int64_t dltotal,
  323. int64_t dlnow, int64_t ultotal, int64_t ulnow){
  324. LOGD("downloading %lld/%lld", dlnow, dltotal);
  325. string msg = LANGUAGEMANAGER->getValue("Downloading") + " %.0f%%";
  326. srv->SetMessage(base::format(msg.c_str(),
  327. dltotal == 0 ? 0 : (dlnow * 1.0/dltotal * 100)));
  328. return 0;
  329. });
  330. if (response.StatusCode() != 200) { // 下载失败
  331. string msg = LANGUAGEMANAGER->getValue("DownloadFailed") + "%d";
  332. srv->SetMessage(base::format(msg.c_str(), response.ErrorCode()));
  333. mProgressWindowPtr->hideWnd();
  334. return -1;
  335. }
  336. // TODO: 应该去判断一下,下载的版本是否真的大于当前版本号
  337. UpgradeMonitor::getInstance()->checkUpgradeFile("/mnt/extsd");
  338. LOGD("img版本-> %s", "");
  339. const char* msg = "-1";
  340. TcpClient::instance()->sendMsg(msg);
  341. system("touch /tmp/zkautoupgrade");
  342. UPGRADEMONITOR->checkUpgradeFile("/tmp");
  343. return 0;
  344. });
  345. }
  346. return false;
  347. }