diff --git a/apps.cpp b/apps.cpp index 00e2df8..19fb1ab 100644 --- a/apps.cpp +++ b/apps.cpp @@ -336,7 +336,12 @@ void apps::showUserApps(bool showDisabledJson) } else { QString function = __func__; log(function + ": JSON is invalid", className); - emit showToast("ERROR: Failed to parse 'apps.json'"); + + ui->editUserAppsBtn->deleteLater(); + ui->label_6->deleteLater(); + ui->horizontalLayout->deleteLater(); + ui->line_2->deleteLater(); + ui->line_3->deleteLater(); } } diff --git a/functions.h b/functions.h index c77092f..7ccbfb9 100644 --- a/functions.h +++ b/functions.h @@ -13,6 +13,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include #include @@ -853,6 +859,90 @@ namespace { return false; } } + void updateUserAppsMainJsonFile() { + QDirIterator appsDir("/mnt/onboard/onboard/.apps", QDirIterator::NoIteratorFlags); + QFile newJsonFile = QFile{"/mnt/onboard/onboard/.apps/apps.json"}; + QJsonDocument newJsonDocument; + QJsonArray array; + + while (appsDir.hasNext()) + { + QDir dir(appsDir.next()); + if(dir.exists() == true) { + if(dir.path().split("/").last().contains(".") == false) { + QFile jsonSmall = QFile{dir.path() + "/app.json"}; + if(jsonSmall.exists() == true) { + jsonSmall.open(QIODevice::ReadOnly | QIODevice::Text); + QString jsonString = jsonSmall.readAll(); + jsonSmall.close(); + + QJsonDocument jsonSmallDoc = QJsonDocument::fromJson(jsonString.toUtf8()); + if(jsonSmallDoc["app"].isObject() == true) { + QJsonObject jsonSmallMainObj = jsonSmallDoc["app"].toObject(); + array.append(jsonSmallMainObj); + + } + else { + log("Error: User application '" + appsDir.path() + "''s JSON file descriptor is missing main object 'app'", "main"); + } + + } + else { + QString message = "User application '" + appsDir.path() + "' does not contain any 'app.json' file: "; + message.append(jsonSmall.fileName()); + log(message, "main"); + } + } + } + } + // https://forum.qt.io/topic/104791/how-i-can-create-json-format-in-qt/5 + QJsonObject root; + root["list"] = array; + newJsonDocument.setObject(root); + + newJsonFile.open(QFile::WriteOnly | QFile::Text | QFile::Truncate); + newJsonFile.write(newJsonDocument.toJson()); + newJsonFile.flush(); + newJsonFile.close(); + } + void updateUserAppsSmallJsonFiles() { + QFile jsonFile = QFile{"/mnt/onboard/onboard/.apps/apps.json"}; + + jsonFile.open(QIODevice::ReadOnly | QIODevice::Text); + QString fileRead = jsonFile.readAll(); + jsonFile.close(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(fileRead.toUtf8()); + + if(jsonDocument["list"].isArray() == true) { + QJsonArray jsonArray = jsonDocument["list"].toArray(); + for(QJsonValueRef refJsonObject: jsonArray) { + QJsonObject jsonMainObject = refJsonObject.toObject(); + QString appName = jsonMainObject["Name"].toString(); + + // This needs to be here and not at the beggining of this function because it is an iterator + QDirIterator appsDir("/mnt/onboard/onboard/.apps", QDirIterator::NoIteratorFlags); + while (appsDir.hasNext()) { + QDir dir(appsDir.next()); + if(dir.exists() == true) { + if(dir.path().split("/").last().toLower().contains(appName.toLower()) == true) { + QJsonObject root; + root["app"] = refJsonObject.toObject();; + QJsonDocument newJsonDocument; + newJsonDocument.setObject(root); + + QFile newSmallJson = QFile{dir.path() + "/" + "app.json"}; + + newSmallJson.open(QIODevice::ReadWrite); + QTextStream stream(&newSmallJson); + stream << newJsonDocument.toJson() << Qt::endl; + newSmallJson.flush(); + newSmallJson.close(); + } + } + } + } + } + } } #endif // FUNCTIONS_H diff --git a/generaldialog.cpp b/generaldialog.cpp index 68469c7..877ec5d 100644 --- a/generaldialog.cpp +++ b/generaldialog.cpp @@ -190,7 +190,7 @@ generalDialog::generalDialog(QWidget *parent) : QTimer::singleShot(50, this, SLOT(adjust_size())); } else if(global::userApps::appCompatibilityDialog == true) { - appCompabilityDialog = true; + appCompatibilityDialog = true; global::userApps::appCompatibilityLastContinueStatus = true; ui->okBtn->setText("Launch"); ui->cancelBtn->setText("Cancel"); diff --git a/generaldialog.h b/generaldialog.h index 1270521..08d1001 100644 --- a/generaldialog.h +++ b/generaldialog.h @@ -32,7 +32,7 @@ public: bool lowBatteryDialog = false; bool usbmsDialog = false; bool textBrowserDialog = false; - bool appCompabilityDialog = false; + bool appCompatibilityDialog = false; bool appInfoDialog = false; bool resetKoboxDialog = false; bool keyboardDialog = false; diff --git a/main.cpp b/main.cpp index 33e9666..2d1bd54 100644 --- a/main.cpp +++ b/main.cpp @@ -27,101 +27,6 @@ #include #include #include -#include - -#include -#include -#include -#include -#include - -void createMainJson() -{ - QDirIterator appsDir("/mnt/onboard/onboard/.apps", QDirIterator::NoIteratorFlags); - QFile newJsonFile = QFile{"/mnt/onboard/onboard/.apps/apps.json"}; - QJsonDocument newJsonDocument; - QJsonArray array; - - while (appsDir.hasNext()) - { - QDir dir(appsDir.next()); - if(dir.exists() == true) { - if(dir.path().split("/").last().contains(".") == false) { - QFile jsonSmall = QFile{dir.path() + "/app.json"}; - if(jsonSmall.exists() == true) { - jsonSmall.open(QIODevice::ReadOnly | QIODevice::Text); - QString jsonString = jsonSmall.readAll(); - jsonSmall.close(); - - QJsonDocument jsonSmallDoc = QJsonDocument::fromJson(jsonString.toUtf8()); - if(jsonSmallDoc["app"].isObject() == true) { - QJsonObject jsonSmallMainObj = jsonSmallDoc["app"].toObject(); - array.append(jsonSmallMainObj); - - } - else { - log("Small JSON user application file is missing main object 'app'", "main"); - } - - } - else { - QString message = "User applications folder does not contain any 'app.json' file: "; - message.append(jsonSmall.fileName()); - log(message, "main"); - } - } - } - } - // https://forum.qt.io/topic/104791/how-i-can-create-json-format-in-qt/5 - QJsonObject root; - root["list"] = array; - newJsonDocument.setObject(root); - - newJsonFile.open(QFile::WriteOnly | QFile::Text | QFile::Truncate); - newJsonFile.write(newJsonDocument.toJson()); - newJsonFile.flush(); - newJsonFile.close(); -} - -void createSmallJsonFiles() -{ - QFile jsonFile = QFile{"/mnt/onboard/onboard/.apps/apps.json"}; - - jsonFile.open(QIODevice::ReadOnly | QIODevice::Text); - QString fileRead = jsonFile.readAll(); - jsonFile.close(); - QJsonDocument jsonDocument = QJsonDocument::fromJson(fileRead.toUtf8()); - - if(jsonDocument["list"].isArray() == true) { - QJsonArray jsonArray = jsonDocument["list"].toArray(); - for(QJsonValueRef refJsonObject: jsonArray) { - QJsonObject jsonMainObject = refJsonObject.toObject(); - QString appName = jsonMainObject["Name"].toString(); - - // This needs to be here and not at the beggining of this function because it is an iterator - QDirIterator appsDir("/mnt/onboard/onboard/.apps", QDirIterator::NoIteratorFlags); - while (appsDir.hasNext()) { - QDir dir(appsDir.next()); - if(dir.exists() == true) { - if(dir.path().split("/").last().toLower().contains(appName.toLower()) == true) { - QJsonObject root; - root["app"] = refJsonObject.toObject();; - QJsonDocument newJsonDocument; - newJsonDocument.setObject(root); - - QFile newSmallJson = QFile{dir.path() + "/" + "app.json"}; - - newSmallJson.open(QIODevice::ReadWrite); - QTextStream stream(&newSmallJson); - stream << newJsonDocument.toJson() << Qt::endl; - newSmallJson.flush(); - newSmallJson.close(); - } - } - } - } - } -} int main(int argc, char *argv[]) { @@ -142,6 +47,13 @@ int main(int argc, char *argv[]) log("Device does not have Wi-Fi capabilities", "main"); global::device::isWifiAble = false; } + + if(QFile::exists("/tmp/rescan_userapps")) { + QFile::remove("/tmp/rescan_userapps"); + log("Re-scanning user applications from explicit request", "main"); + updateUserAppsMainJsonFile(); + } + if(checkconfig(".config/18-encrypted_storage/status") == true and checkconfig("/external_root/run/encfs_mounted") == false) { // Open Encryption Manager to unlock encrypted storage QApplication a(argc, argv); diff --git a/quit.cpp b/quit.cpp index 1114929..63b242f 100644 --- a/quit.cpp +++ b/quit.cpp @@ -51,6 +51,9 @@ void quit::on_pushButton_clicked() global::battery::showCriticalBatteryAlert = false; global::battery::showLowBatteryDialog = false; + // GUI apps + updateUserAppsMainJsonFile(); + poweroff(true); qApp->quit(); } @@ -60,6 +63,9 @@ void quit::on_pushButton_2_clicked() global::battery::showCriticalBatteryAlert = false; global::battery::showLowBatteryDialog = false; + // GUI apps + updateUserAppsMainJsonFile(); + reboot(true); qApp->quit(); } diff --git a/usbms_splash.cpp b/usbms_splash.cpp index ea49d70..692e256 100644 --- a/usbms_splash.cpp +++ b/usbms_splash.cpp @@ -85,6 +85,9 @@ void usbms_splash::usbms_launch() string_writeconfig("/opt/ibxd", "usbnet_stop\n"); QThread::msleep(1000); + string_writeconfig("/opt/ibxd", "gui_apps_stop\n"); + QThread::msleep(1000); + if(global::deviceID == "n306\n" or global::deviceID == "n873\n") { QProcess::execute("insmod", QStringList() << "/external_root/lib/modules/fs/configfs/configfs.ko"); QProcess::execute("insmod", QStringList() << "/external_root/lib/modules/drivers/usb/gadget/libcomposite.ko"); @@ -197,6 +200,22 @@ void usbms_splash::restartServices() { string_writeconfig("/opt/ibxd", "update_inkbox_restart\n"); QThread::msleep(2500); string_writeconfig("/tmp/in_usbms", "false"); + // GUI apps: update main JSON file + string_writeconfig("/opt/ibxd", "gui_apps_start\n"); + while(true) { + if(QFile::exists("/tmp/gui_apps_started")) { + if(checkconfig("/tmp/gui_apps_started") == true) { + QFile::remove("/tmp/gui_apps_started"); + updateUserAppsMainJsonFile(); + break; + } + else { + log("GUI apps service failed to start", className); + QFile::remove("/tmp/gui_apps_started"); + break; + } + } + } quit_restart(); } diff --git a/userapps.cpp b/userapps.cpp index f9beb77..353865d 100644 --- a/userapps.cpp +++ b/userapps.cpp @@ -30,8 +30,7 @@ void userapps::provideInfo(QJsonObject jsonInfo) appName = name; // It is for searching for json entry while disabling / enabling jsonObject = jsonInfo; // Limit name size to avoid breaking the GUI - if(name.size() > 20) - { + if(name.size() > 20) { // If someone wants to break the GUI, they will do it ¯\^-^/¯ name.remove(16, 100); } @@ -91,7 +90,7 @@ void userapps::on_statusBtn_clicked() { ui->statusBtn->setEnabled(false); - // Here the text on this button is used as a bool. No need to create a new one + // Here the text on this button is used as a boolean; no need to create a new one // Disable and Enable if(userAppEnabled == false) { userAppEnabled = true; @@ -107,13 +106,11 @@ void userapps::on_statusBtn_clicked() int arraySize = jsonArrayList.size(); - for(int i = 0; i < arraySize; i++) - { + for(int i = 0; i < arraySize; i++) { QJsonObject jsonObject = jsonArrayList.at(i).toObject(); QString entryName = jsonObject["Name"].toString(); - if(entryName == appName) - { + if(entryName == appName) { jsonObject.insert("Enabled", QJsonValue(userAppEnabled)); QJsonArray sonArrayListNew = jsonDocument.object()["list"].toArray(); @@ -173,8 +170,7 @@ void userapps::on_launchBtn_clicked() bool userapps::manageRequiredFeatures() { QJsonArray jsonArray = jsonObject["RequiredFeatures"].toArray(); - for(QJsonValueRef refJsonObject: jsonArray) - { + for(QJsonValueRef refJsonObject: jsonArray) { bool launchDialog = false; int featureId = refJsonObject.toInt(); // Wi-Fi connection required @@ -188,16 +184,14 @@ bool userapps::manageRequiredFeatures() launchDialog = true; } - if(launchDialog == true) - { + if(launchDialog == true) { global::userApps::appCompatibilityDialog = true; generalDialogWindow = new generalDialog(); generalDialogWindow->setAttribute(Qt::WA_DeleteOnClose); generalDialogWindow->exec(); } - if(global::userApps::appCompatibilityLastContinueStatus == false) - { + if(global::userApps::appCompatibilityLastContinueStatus == false) { return false; } } @@ -226,11 +220,10 @@ QString userapps::parseJsonShow(QJsonObject json) QJsonArray array = value.toArray(); for(QJsonValueRef ref: array) { int id = ref.toInt(); - if(id == 0) - { + if(id == 0) { appendString.append("Wi-Fi connection"); - } else if(id == 1) - { + } + else if(id == 1) { appendString.append("Rooted kernel"); } appendString.append(", ");