nanoapp_cmd: add ability to uninstall a nanoapp
Bug: 36370644
Test: change activity to "uninstall 476f6f676c001000 c" in napp_list.cfg
and verify old activity nanoapp is removed
Signed-off-by: Ben Fennema <fennema@google.com>
Change-Id: I6a49af77bca3998c48b6fac3280abdd58e776bfe
diff --git a/util/nanoapp_cmd/Android.mk b/util/nanoapp_cmd/Android.mk
index 80af754..83386c0 100644
--- a/util/nanoapp_cmd/Android.mk
+++ b/util/nanoapp_cmd/Android.mk
@@ -19,7 +19,10 @@
LOCAL_SRC_FILES:= nanoapp_cmd.c
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../firmware/os/inc
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/../../firmware/os/inc \
+ $(LOCAL_PATH)/../../lib/include
+
LOCAL_CFLAGS := -Wall -Werror -Wextra
LOCAL_MODULE:= nanoapp_cmd
diff --git a/util/nanoapp_cmd/nanoapp_cmd.c b/util/nanoapp_cmd/nanoapp_cmd.c
index 6c1f6da..9df2eea 100644
--- a/util/nanoapp_cmd/nanoapp_cmd.c
+++ b/util/nanoapp_cmd/nanoapp_cmd.c
@@ -32,14 +32,20 @@
#include <android/log.h>
+#include <nanohub/nanohub.h>
#include <eventnums.h>
#include <sensType.h>
#define SENSOR_RATE_ONCHANGE 0xFFFFFF01UL
#define SENSOR_RATE_ONESHOT 0xFFFFFF02UL
#define SENSOR_HZ(_hz) ((uint32_t)((_hz) * 1024.0f))
+#define MAX_APP_NAME_LEN 32
#define MAX_INSTALL_CNT 8
+#define MAX_UNINSTALL_CNT 8
#define MAX_DOWNLOAD_RETRIES 4
+#define UNINSTALL_CMD "uninstall"
+
+#define NANOHUB_EXT_APP_DELETE 2
#define LOGE(fmt, ...) do { \
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, fmt, ##__VA_ARGS__); \
@@ -65,7 +71,7 @@
uint16_t flags;
} __attribute__((packed));
-struct AppInfo
+struct App
{
uint32_t num;
uint64_t id;
@@ -158,9 +164,10 @@
bool stop = false;
char *buf;
int nread, buf_size = 2048;
-struct AppInfo apps[32];
+struct App apps[32];
uint8_t appCount;
-char appsToInstall[MAX_INSTALL_CNT][32];
+char appsToInstall[MAX_INSTALL_CNT][MAX_APP_NAME_LEN+1];
+uint64_t appsToUninstall[MAX_UNINSTALL_CNT];
void sig_handle(__attribute__((unused)) int sig)
{
@@ -192,7 +199,7 @@
return;
while ((numRead = getline(&line, &len, fp)) != -1) {
- struct AppInfo *currApp = &apps[appCount++];
+ struct App *currApp = &apps[appCount++];
sscanf(line, "app: %d id: %" PRIx64 " ver: %" PRIx32 " size: %" PRIx32 "\n", &currApp->num, &currApp->id, &currApp->version, &currApp->size);
}
@@ -202,7 +209,7 @@
free(line);
}
-struct AppInfo *findApp(uint64_t appId)
+struct App *findApp(uint64_t appId)
{
uint8_t i;
@@ -215,13 +222,12 @@
return NULL;
}
-int parseConfigAppInfo()
+int parseConfigAppInfo(int *installCnt, int *uninstallCnt)
{
FILE *fp;
char *line = NULL;
size_t len;
ssize_t numRead;
- int installCnt;
fp = openFile("/vendor/firmware/napp_list.cfg", "r");
if (!fp)
@@ -229,17 +235,22 @@
parseInstalledAppInfo();
- installCnt = 0;
- while (((numRead = getline(&line, &len, fp)) != -1) && (installCnt < MAX_INSTALL_CNT)) {
+ *installCnt = *uninstallCnt = 0;
+ while (((numRead = getline(&line, &len, fp)) != -1) && (*installCnt < MAX_INSTALL_CNT) && (*uninstallCnt < MAX_UNINSTALL_CNT)) {
uint64_t appId;
uint32_t appVersion;
- struct AppInfo* installedApp;
+ struct App *installedApp;
- sscanf(line, "%32s %" PRIx64 " %" PRIx32 "\n", appsToInstall[installCnt], &appId, &appVersion);
+ sscanf(line, "%" STRINGIFY(MAX_APP_NAME_LEN) "s %" PRIx64 " %" PRIx32 "\n", appsToInstall[*installCnt], &appId, &appVersion);
installedApp = findApp(appId);
- if (!installedApp || (installedApp->version < appVersion)) {
- installCnt++;
+ if (strncmp(appsToInstall[*installCnt], UNINSTALL_CMD, MAX_APP_NAME_LEN) == 0) {
+ if (installedApp) {
+ appsToUninstall[*uninstallCnt] = appId;
+ (*uninstallCnt)++;
+ }
+ } else if (!installedApp || (installedApp->version < appVersion)) {
+ (*installCnt)++;
}
}
@@ -248,7 +259,7 @@
if (line)
free(line);
- return installCnt;
+ return *installCnt + *uninstallCnt;
}
bool fileWriteData(const char *fname, const void *data, size_t size)
@@ -282,6 +293,27 @@
printf("done\n");
}
+void removeApps(int updateCnt)
+{
+ uint8_t buffer[sizeof(struct HostMsgHdr) + 1 + sizeof(uint64_t)];
+ struct HostMsgHdr *mHostMsgHdr = (struct HostMsgHdr *)(&buffer[0]);
+ uint8_t *cmd = (uint8_t *)(&buffer[sizeof(struct HostMsgHdr)]);
+ uint64_t *appId = (uint64_t *)(&buffer[sizeof(struct HostMsgHdr) + 1]);
+ int i;
+
+ for (i = 0; i < updateCnt; i++) {
+ mHostMsgHdr->eventId = EVT_APP_FROM_HOST;
+ mHostMsgHdr->appId = APP_ID_MAKE(NANOHUB_VENDOR_GOOGLE, 0);
+ mHostMsgHdr->len = 1 + sizeof(uint64_t);
+ *cmd = NANOHUB_EXT_APP_DELETE;
+ memcpy(appId, &appsToUninstall[i], sizeof(uint64_t));
+ printf("Deleting \"%016" PRIx64 "\"...", appsToUninstall[i]);
+ fflush(stdout);
+ if (fileWriteData("/dev/nanohub", buffer, sizeof(buffer)))
+ printf("done\n");
+ }
+}
+
void downloadApps(int updateCnt)
{
int i;
@@ -390,27 +422,31 @@
return 1;
}
} else if (strcmp(argv[1], "download") == 0) {
+ int installCnt, uninstallCnt;
+
if (argc != 2) {
printf("Wrong arg number\n");
return 1;
}
downloadNanohub();
for (i = 0; i < MAX_DOWNLOAD_RETRIES; i++) {
- int updateCnt = parseConfigAppInfo();
+ int updateCnt = parseConfigAppInfo(&installCnt, &uninstallCnt);
if (updateCnt > 0) {
if (i == MAX_DOWNLOAD_RETRIES - 1) {
LOGE("Download failed after %d retries; erasing all apps "
"before final attempt", i);
eraseSharedArea();
+ uninstallCnt = 0;
}
- downloadApps(updateCnt);
+ removeApps(uninstallCnt);
+ downloadApps(installCnt);
resetHub();
} else if (!updateCnt){
return 0;
}
}
- if (parseConfigAppInfo() != 0) {
+ if (parseConfigAppInfo(&installCnt, &uninstallCnt) != 0) {
LOGE("Failed to download all apps!");
}
return 1;