4 * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
29 #include <sys/types.h>
32 #include <storage-internal.h>
33 #include <tzplatform_config.h>
35 #include "app2ext_interface.h"
40 #define TEST_PKGNAME "org.example.basicuiapplication"
41 #define TEST_PKGNAME_PATH "/tmp/org.example.basicuiapplication-1.0.0-arm.tpk"
43 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
45 app2ext_handle *handle = NULL;
47 char pkg_ro_content_rpm[3][5] = { "bin", "res", "lib" };
49 #define COUNT_OF_ERROR_LIST APP2EXT_ERROR_ENUM_MAX
50 char error_list[COUNT_OF_ERROR_LIST][100] = {
52 "APP2EXT_ERROR_UNKNOWN",
53 "APP2EXT_ERROR_INVALID_ARGUMENTS",
55 "APP2EXT_ERROR_PRE_UNINSTALL",
56 "APP2EXT_ERROR_MMC_STATUS",
57 "APP2EXT_ERROR_DB_INITIALIZE",
58 "APP2EXT_ERROR_SQLITE_REGISTRY",
59 "APP2EXT_ERROR_PASSWD_GENERATION",
60 "APP2EXT_ERROR_MMC_INFORMATION",
61 "APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY",
62 "APP2EXT_ERROR_DELETE_DIRECTORY",
63 "APP2EXT_ERROR_CREATE_SYMLINK",
64 "APP2EXT_ERROR_CREATE_DIRECTORY",
65 "APP2EXT_ERROR_DELETE_LINK_FILE",
66 "APP2EXT_ERROR_PKG_EXISTS",
67 "APP2EXT_ERROR_ACCESS_FILE",
68 "APP2EXT_ERROR_OPEN_DIR",
69 "APP2EXT_ERROR_ALREADY_FILE_PRESENT",
70 "APP2EXT_ERROR_FILE_ABSENT",
71 "APP2EXT_ERROR_STRCMP_FAILED",
72 "APP2EXT_ERROR_INVALID_PACKAGE",
73 "APP2EXT_ERROR_CREATE_DIR_ENTRY",
74 "APP2EXT_ERROR_COPY_DIRECTORY",
75 "APP2EXT_ERROR_INVALID_CASE",
76 "APP2EXT_ERROR_SYMLINK_ALREADY_EXISTS",
77 "APP2EXT_ERROR_APPEND_HASH_TO_FILE",
78 "APP2EXT_ERROR_CREATE_DEVICE",
79 "APP2EXT_ERROR_DO_LOSETUP",
80 "APP2EXT_ERROR_CREATE_FS",
81 "APP2EXT_ERROR_MOUNT_PATH",
82 "APP2EXT_ERROR_CLEANUP",
83 "APP2EXT_ERROR_MOUNT",
84 "APP2EXT_ERROR_REMOUNT",
85 "APP2EXT_ERROR_PIPE_CREATION",
86 "APP2EXT_ERROR_LOOPBACK_DEVICE_UNAVAILABLE",
87 "APP2EXT_ERROR_VCONF_REGISTRY",
88 "APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE",
89 "APP2EXT_ERROR_UNMOUNT",
90 "APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE",
91 "APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE",
92 "APP2EXT_ERROR_ALREADY_MOUNTED",
93 "APP2EXT_ERROR_PLUGIN_INIT_FAILED",
94 "APP2EXT_ERROR_PLUGIN_DEINIT_FAILED",
95 "APP2EXT_ERROR_DBUS_FAILED",
96 "APP2EXT_ERROR_MEMORY_ALLOC_FAILED",
97 "APP2EXT_ERROR_OPERATION_NOT_PERMITTED",
98 "APP2EXT_ERROR_SAME_LOOPBACK_DEVICE_EXISTS",
99 "APP2EXT_ERROR_PKGMGR_ERROR",
100 "APP2EXT_ERROR_NOENTRY",
101 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
102 "APP2EXT_ERROR_SETUP_DMCRYPT_DEVICE",
103 "APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE",
104 "APP2EXT_ERROR_CLOSE_DMCRYPT_DEVICE",
105 "APP2EXT_ERROR_FIND_ASSOCIATED_DMCRYPT_DEVICE_NODE",
106 "APP2EXT_ERROR_DMCRYPT_DEVICE_UNAVAILABLE",
110 static void usage(void)
113 printf("*************************************************\n");
114 printf("App2sd test usage:\n");
115 printf("Pre-condition: /tmp/org.example.basicuiapplication-1.0.0-arm.tpk\n");
116 printf("All tests assume the target uid as default user.\n");
118 printf("<INSTALL>\n");
119 printf("1.#test_app2ext --pre-install\n");
120 printf("2.#pkgcmd -it tpk {pkg-path}\n");
121 printf("3.#test_app2ext --post-install\n");
122 printf("------------------------------------------------\n");
124 printf("<UPGRADE>\n");
125 printf("1.#test_app2ext --pre-upgrade\n");
126 printf("2.#pkgcmd -it tpk {pkg-path}\n");
127 printf("3.#test_app2ext --post-upgrade\n");
128 printf("------------------------------------------------\n");
130 printf("<INSTALL>\n");
131 printf("1.#test_app2ext --pre-uninstall\n");
132 printf("2.#pkgcmd -un {pkg-id}\n");
133 printf("3.#test_app2ext --post-uninstall\n");
134 printf("------------------------------------------------\n");
136 printf("<MOVE PKG TEST>\n");
137 printf("#test_app2ext --move-to-ext\n");
138 printf("#test_app2ext --move-to-int\n");
139 printf("------------------------------------------------\n");
141 printf("<ENABLE(mount)/DISABLE(umount) TEST W/ Installed PKG>\n");
142 printf("#test_app2ext --enable\n");
143 printf("#test_app2ext --disable\n");
144 printf("#test_app2ext --enable-full\n");
145 printf("#test_app2ext --disable-full\n");
146 printf("------------------------------------------------\n");
148 printf("<MIGRATION TRIGGER TEST>\n");
149 printf("Pre-condition: install test package and copy legacy image to app2sd.\n");
150 printf("#test_app2ext --migrate-all\n");
151 printf("------------------------------------------------\n");
152 printf("**************************************************\n");
156 #define OPTVAL_PRE_INSTALL 1000
157 #define OPTVAL_POST_INSTALL 1001
158 #define OPTVAL_PRE_UNINSTALL 1002
159 #define OPTVAL_POST_UNINSTALL 1003
160 #define OPTVAL_PRE_UPGRADE 1004
161 #define OPTVAL_POST_UPGRADE 1005
162 #define OPTVAL_MOVE_TO_EXTERNAL 1006
163 #define OPTVAL_MOVE_TO_INTERNAL 1007
164 #define OPTVAL_ENABLE_APP 1008
165 #define OPTVAL_DISABLE_APP 1009
166 #define OPTVAL_ENABLE_FULL 1010
167 #define OPTVAL_DISABLE_FULL 1011
168 #define OPTVAL_MIGRATE_ALL 1012
169 #define OPTVAL_USAGE 1013
171 /* Supported options */
172 const struct option long_opts[] = {
173 { "pre-install", 0, NULL, OPTVAL_PRE_INSTALL },
174 { "post-install", 0, NULL, OPTVAL_POST_INSTALL },
175 { "pre-uninstall", 0, NULL, OPTVAL_PRE_UNINSTALL },
176 { "post-uninstall", 0, NULL, OPTVAL_POST_UNINSTALL },
177 { "pre-upgrade", 0, NULL, OPTVAL_PRE_UPGRADE },
178 { "post-upgrade", 0, NULL, OPTVAL_POST_UPGRADE },
179 { "move-to-ext", 0, NULL, OPTVAL_MOVE_TO_EXTERNAL },
180 { "move-to-int", 0, NULL, OPTVAL_MOVE_TO_INTERNAL },
181 { "enable", 0, NULL, OPTVAL_ENABLE_APP },
182 { "disable", 0, NULL, OPTVAL_DISABLE_APP },
183 { "enable-full", 0, NULL, OPTVAL_ENABLE_FULL },
184 { "disable-full", 0, NULL, OPTVAL_DISABLE_FULL },
185 { "migrate-all", 0, NULL, OPTVAL_MIGRATE_ALL },
186 { "help", 0, NULL, OPTVAL_USAGE },
187 { "usage", 0, NULL, OPTVAL_USAGE },
188 { 0, 0, 0, 0 } /* sentinel */
191 void clear_dir_list(GList *dir_list)
194 app2ext_dir_details *dir_detail = NULL;
197 list = g_list_first(dir_list);
199 dir_detail = (app2ext_dir_details *)list->data;
200 if (dir_detail && dir_detail->name)
201 free(dir_detail->name);
203 list = g_list_next(list);
205 g_list_free(dir_list);
209 GList *populate_dir_details()
211 GList *dir_list = NULL;
213 app2ext_dir_details *dir_detail = NULL;
216 for (i = 0; i < 3; i++) {
217 dir_detail = (app2ext_dir_details *)calloc(1, sizeof(app2ext_dir_details));
218 if (dir_detail == NULL) {
219 printf("memory allocation failed\n");
223 dir_detail->name = (char *)calloc(1, sizeof(char) * (strlen(pkg_ro_content_rpm[i]) + 2));
224 if (dir_detail->name == NULL) {
225 printf("memory allocation failed\n");
229 snprintf(dir_detail->name, (strlen(pkg_ro_content_rpm[i]) + 1), "%s", pkg_ro_content_rpm[i]);
230 dir_detail->type = APP2EXT_DIR_RO;
231 dir_list = g_list_append(dir_list, dir_detail);
235 list = g_list_first(dir_list);
237 dir_detail = (app2ext_dir_details *)list->data;
238 list = g_list_next(list);
246 clear_dir_list(dir_list);
251 static int get_unzip_size(const char *item, unsigned long long *size)
255 char *filename = NULL;
256 unz_file_info fileInfo = { 0 };
258 if (!item || !size) {
259 printf("get size : invalid argument\n");
262 uzf = unzOpen64(item);
264 printf("get size : failed to open item : [%s]\n", item);
268 ret = unzGoToFirstFile(uzf);
270 printf("get size : error get first zip file\n");
276 ret = unzOpenCurrentFile(uzf);
278 printf("get size : error unzOpenCurrentFile\n");
284 filename = (char *)calloc(1, 4096);
285 ret = unzGetCurrentFileInfo(uzf, &fileInfo, filename, (4096 - 1), NULL, 0, NULL, 0);
286 *size = (unsigned long long)fileInfo.uncompressed_size + *size;
288 printf("get size : error get current file info\n");
289 unzCloseCurrentFile(uzf);
298 } while (unzGoToNextFile(uzf) == UNZ_OK);
306 static void print_error_code(const char *func_name, int ret)
308 if (ret < 0 || ret > COUNT_OF_ERROR_LIST - 1)
309 printf("%s failed : unknown error(%d)\n", func_name, ret);
311 printf("%s return(%s)\n", func_name, error_list[ret]);
314 static int pre_app_install()
316 GList *dir_list = NULL;
318 unsigned long long size_byte = 0;
321 printf("pre_app_install for [%s]\n", TEST_PKGNAME_PATH);
323 dir_list = populate_dir_details();
324 if (dir_list == NULL) {
325 printf("error in populating the directory list\n");
330 ret = get_unzip_size(TEST_PKGNAME_PATH, &size_byte);
331 if (ret < 0 || size_byte == 0)
332 printf("wrong pkg size, ret(%d), size_byte(%llu)\n", ret, size_byte);
334 size_mega = size_byte / (1024 * 1024) + 1;
335 printf("get pkg size : (%d)MB\n", size_mega);
337 ret = handle->interface.client_pre_install(TEST_PKGNAME,
338 dir_list, size_mega);
339 print_error_code(__func__, ret);
341 clear_dir_list(dir_list);
346 static int post_app_install()
350 ret = handle->interface.client_post_install(TEST_PKGNAME,
351 APP2EXT_STATUS_SUCCESS);
352 print_error_code(__func__, ret);
357 static int app_enable()
361 ret = handle->interface.client_enable(TEST_PKGNAME);
362 print_error_code(__func__, ret);
367 static int app_disable()
371 ret = handle->interface.client_disable(TEST_PKGNAME);
372 print_error_code(__func__, ret);
377 static int fullpkg_enable()
381 ret = handle->interface.client_enable_full_pkg();
382 print_error_code(__func__, ret);
387 static int fullpkg_disable()
391 ret = handle->interface.client_disable_full_pkg();
392 print_error_code(__func__, ret);
397 static int migrate_all()
401 ret = handle->interface.client_migrate_legacy_all();
402 print_error_code(__func__, ret);
407 static int pre_app_uninstall()
411 printf("pre_app_uninstall for [%s]\n", TEST_PKGNAME);
413 ret = handle->interface.client_pre_uninstall(TEST_PKGNAME);
414 print_error_code(__func__, ret);
419 static int post_app_uninstall()
423 ret = handle->interface.client_post_uninstall(TEST_PKGNAME);
424 print_error_code(__func__, ret);
429 static int pre_app_upgrade()
431 GList *dir_list = NULL;
433 unsigned long long size_byte = 0;
436 printf("pre_app_upgrade for [%s]\n", TEST_PKGNAME);
438 dir_list = populate_dir_details();
439 if (dir_list == NULL) {
440 printf("Error in populating the directory list\n");
445 ret = get_unzip_size(TEST_PKGNAME_PATH, &size_byte);
446 if (ret < 0 || size_byte == 0)
447 printf("wrong pkg size, ret(%d), size_byte(%llu)\n", ret, size_byte);
449 size_mega = size_byte / (1024 * 1024) + 1;
450 printf("get pkg size : (%d)MB\n", size_mega);
452 ret = handle->interface.client_pre_upgrade(TEST_PKGNAME, dir_list,
454 print_error_code(__func__, ret);
456 clear_dir_list(dir_list);
461 static int post_app_upgrade()
465 ret = handle->interface.client_post_upgrade(TEST_PKGNAME,
466 APP2EXT_STATUS_SUCCESS);
467 print_error_code(__func__, ret);
472 static int app_move_to_external()
474 GList *dir_list = NULL;
477 printf("app_move_to_external %s\n", TEST_PKGNAME);
479 dir_list = populate_dir_details();
480 if (dir_list == NULL) {
481 printf("Error in populating the directory list\n");
485 printf("pkg %s will be moved to sd card\n", TEST_PKGNAME);
486 ret = handle->interface.client_pre_move(TEST_PKGNAME,
487 dir_list, APP2EXT_MOVE_TO_EXT);
488 print_error_code(__func__, ret);
489 ret = handle->interface.client_post_move(TEST_PKGNAME,
490 APP2EXT_MOVE_TO_EXT);
491 print_error_code(__func__, ret);
493 clear_dir_list(dir_list);
498 static int app_move_to_internal()
500 GList *dir_list = NULL;
503 printf("app_move_to_internal %s\n", TEST_PKGNAME);
505 dir_list = populate_dir_details();
506 if (dir_list == NULL) {
507 printf("Error in populating the directory list\n");
511 printf("pkg %s will be moved to internal memory\n", TEST_PKGNAME);
512 ret = handle->interface.client_pre_move(TEST_PKGNAME,
513 dir_list, APP2EXT_MOVE_TO_PHONE);
514 print_error_code(__func__, ret);
515 ret = handle->interface.client_post_move(TEST_PKGNAME,
516 APP2EXT_MOVE_TO_PHONE);
517 print_error_code(__func__, ret);
519 clear_dir_list(dir_list);
524 int main(int argc, char **argv)
530 char *sd_mount_path = NULL;
531 uid_t uid = getuid();
534 if (uid != OWNER_ROOT) {
535 printf("only root user allowed\n");
539 /* check sdcard info */
540 ret = storage_get_primary_sdcard(&storage_id, &sd_mount_path);
541 if (ret != STORAGE_ERROR_NONE) {
542 printf("failed to get primary sdcard (%d)\n", ret);
548 printf("primary sdcard: id(%d), mount_path(%s)\n",
549 storage_id, sd_mount_path);
552 printf("there is no primary sdcard\n");
555 handle = app2ext_init(APP2EXT_SD_CARD);
556 if (handle == NULL) {
557 ret = APP2EXT_ERROR_PLUGIN_INIT_FAILED;
558 printf("app2ext_init failed (%s)\n", error_list[ret]);
563 optind = 1; /* Initialize optind to clear prev. index */
565 c = getopt_long(argc, argv, "", long_opts, &opt_idx);
568 break; /* Parse is end */
571 case OPTVAL_PRE_INSTALL:
574 case OPTVAL_POST_INSTALL:
577 case OPTVAL_PRE_UNINSTALL:
580 case OPTVAL_POST_UNINSTALL:
581 post_app_uninstall();
583 case OPTVAL_PRE_UPGRADE:
586 case OPTVAL_POST_UPGRADE:
589 case OPTVAL_MOVE_TO_EXTERNAL:
590 app_move_to_external();
592 case OPTVAL_MOVE_TO_INTERNAL:
593 app_move_to_internal();
595 case OPTVAL_ENABLE_APP:
598 case OPTVAL_DISABLE_APP:
601 case OPTVAL_ENABLE_FULL:
604 case OPTVAL_DISABLE_FULL:
607 case OPTVAL_MIGRATE_ALL:
619 app2ext_deinit(handle);