SET(EXTRA_CFLAGS_COMMON "${EXTRA_CFLAGS_COMMON} -DREAD_ONLY_APP_UPDATE_DIR=${READ_ONLY_APP_UPDATE_DIR}")
ENDIF(DEFINED READ_ONLY_APP_UPDATE_DIR)
+IF(DEFINED READ_ONLY_TAC_DIR)
+ SET(EXTRA_CFLAGS_COMMON "${EXTRA_CFLAGS_COMMON} -DREAD_ONLY_TAC_DIR=${READ_ONLY_TAC_DIR}")
+ENDIF(DEFINED READ_ONLY_TAC_DIR)
+
IF(DEFINED USE_DEFAULT_BASE_ADDR)
SET(EXTRA_CFLAGS_COMMON "${EXTRA_CFLAGS_COMMON} -DUSE_DEFAULT_BASE_ADDR")
ENDIF(DEFINED USE_DEFAULT_BASE_ADDR)
#define APP_NI_SUB_TMP_DIR ".native_image_tmp"
#define TAC_SYMLINK_SUB_DIR ".tac_symlink"
#define TAC_SHA_256_INFO ".SHA256.info"
-#define TAC_APP_LIST_DB "/opt/usr/dotnet/.TAC.App.list.db"
-#define TAC_APP_LIST_RESTORE_DB "/opt/usr/dotnet/.TAC.App.list.restore.db"
-#define TLC_APP_LIST_DB "/opt/usr/dotnet/.TLC.App.list.db"
-#define TLC_APP_LIST_RESTORE_DB "/opt/usr/dotnet/.TLC.App.list.restore.db"
-#define TLC_LIBRARIES_DIR "/opt/usr/dotnet/Libraries"
+#define TAC_APP_LIST_DB ".TAC.App.list.db"
+#define TAC_APP_LIST_RESTORE_DB ".TAC.App.list.restore.db"
+#define TLC_APP_LIST_DB ".TLC.App.list.db"
+#define TLC_APP_LIST_RESTORE_DB ".TLC.App.list.restore.db"
+#define TLC_LIBRARIES_DIR "Libraries"
#define TIZEN_DOTNET_NUGET "Tizen.NET"
#define TIZEN_DOTNET_SDK_NUGET "Tizen.NET.Sdk"
#define NET_STANDARD_LIBRARY_NUGET "NETStandard.Library"
/**
* @brief restore database of TAC
+ * @param[in] tac readonly flag
* @return tac_error_e
*/
-tac_error_e tac_restoreDB();
+tac_error_e tac_restoreDB(bool isReadonly);
/**
* @brief disable tac feature.
/**
* @brief restore database of TLC
+ * @param[in] tlc readonly flag
* @return tac_error_e
*/
-tac_error_e tlc_restoreDB();
+tac_error_e tlc_restoreDB(bool isReadonly);
#endif /* __TAC_COMMON_H__ */
/* TAC related DB functions */
-int tac_createDB();
+int tac_createDB(bool isReadonly);
-int tac_openDB();
+int tac_openDB(bool isReadonly);
int tac_insertDB(const std::string& pkgId, const std::string& np, const std::string& tac_name, const std::string& tac_version);
/* TAC related DB functions */
-int tlc_createDB();
+int tlc_createDB(bool isReadonly);
-int tlc_openDB();
+int tlc_openDB(bool isReadonly);
int tlc_insertDB(const std::string& pkgId, const std::string& fileSha);
bool isReadOnlyArea(const std::string& path);
/**
+ * @brief check the package is 'readonly' or not
+ * @param[in] package ID
+ * @return bool package readonly value
+ */
+bool isReadOnlyPkg(const std::string& pkgId);
+
+/**
+ * @brief get db path of tac
+ * @param[in] tac readonly flag
+ * @param[in] db file name
+ * @return tac db path
+ */
+std::string tacDBPath(bool isReadonly, const std::string& dbName);
+
+/**
+ * @brief get library path of tlc
+ * @param[in] tlac readonly flag
+ * @return tlc library path
+ */
+std::string tlcLBPath(bool isReadonly);
+
+/**
* @brief split path with ":" delimiter and put that in the vector
* @param[in] source path
* @param[out] string vector
}
//sh-3.2# dotnettool --tac-restore-db
else if (cmd == "--tac-restore-db") {
- int ret = tac_restoreDB();
- if (ret != TAC_ERROR_NONE) {
- _SERR("Failed to restore TAC db");
+ if (tac_restoreDB(false) != TAC_ERROR_NONE) {
+ _SERR("Failed to restore TAC db of RW");
}
- ret = tlc_restoreDB();
- if (ret != TAC_ERROR_NONE) {
- _SERR("Failed to restore TLC db");
+ if (tlc_restoreDB(false) != TAC_ERROR_NONE) {
+ _SERR("Failed to restore TLC db of RW");
+ }
+ if (tac_restoreDB(true) != TAC_ERROR_NONE) {
+ _SERR("Failed to restore TAC db of RO");
+ }
+ if (tlc_restoreDB(true) != TAC_ERROR_NONE) {
+ _SERR("Failed to restore TLC db of RO");
}
}
//sh-3.2# dotnettool --tac-enable-pkg [pkgId] [pkgId] ...
return doAOTList(dllList, refPaths, opt);
}
-static bool isReadOnlyPkg(std::string pkgId)
+static ni_error_e removeAndCreateNI(const char* pkgId, NIOption* pOptions)
{
- int ret = 0;
- bool readonly = false;
- pkgmgrinfo_pkginfo_h handle;
-
- ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &handle);
- if (ret != PMINFO_R_OK) {
- _ERR("Fail to get pkginfo");
- return false;
+ if (removeNIUnderPkgRoot(pkgId) != NI_ERROR_NONE) {
+ _SERR("Failed to remove previous dlls from [%s]", pkgId);
+ return NI_ERROR_UNKNOWN;
}
- ret = pkgmgrinfo_pkginfo_is_readonly(handle, &readonly);
- if (ret != PMINFO_R_OK) {
- _ERR("Fail to get is_readonly");
- pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
- return false;
+ if (createNIUnderPkgRoot(pkgId, pOptions) != NI_ERROR_NONE) {
+ _SERR("Failed to generate NI file [%s]", pkgId);
+ return NI_ERROR_UNKNOWN;
}
- pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
- return readonly;
+ _SOUT("Complete make native image for pkg (%s)", pkgId);
+ return NI_ERROR_NONE;
}
// callback function of "pkgmgrinfo_appinfo_metadata_filter_foreach"
return 0;
}
- sqlite3 *tac_db = openDB(TAC_APP_LIST_DB);
+ sqlite3 *tac_db = openDB(concatPath(__DOTNET_DIR, TAC_APP_LIST_DB));
if (!tac_db) {
_SERR("Sqlite open error");
return -1;
#define __STR(x) __XSTR(x)
static const char* __DOTNET_DIR = __STR(DOTNET_DIR);
static const char* __READ_ONLY_APP_UPDATE_DIR = __STR(READ_ONLY_APP_UPDATE_DIR);
+static const char* __READ_ONLY_TAC_DIR = __STR(READ_ONLY_TAC_DIR);
#undef __STR
#undef __XSTR
static std::vector<std::string> restore_nuget;
static std::vector<std::string> restore_library;
-static void cleanupDirectory()
+static void cleanupDirectory(bool isReadonly)
{
std::vector<std::string> removeNuget;
try {
- for (auto& nuget : bf::recursive_directory_iterator(__DOTNET_DIR)) {
+ std::string tacLocation = isReadonly ? __READ_ONLY_TAC_DIR : __DOTNET_DIR;
+ for (auto& nuget : bf::recursive_directory_iterator(tacLocation)) {
std::string nugetPath = nuget.path().string();
if (!bf::is_directory(nugetPath) ||
- nugetPath.find(TLC_LIBRARIES_DIR) != std::string::npos ||
+ nugetPath.find(tlcLBPath(isReadonly)) != std::string::npos ||
nugetPath.find(__READ_ONLY_APP_UPDATE_DIR) != std::string::npos) {
continue;
}
char *pkgId = NULL;
char *root = NULL;
char *exec = NULL;
+ bool *isReadOnly = (bool*)userData;
int ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgId);
if (ret != PMINFO_R_OK) {
return -1;
}
+ if (userData == NULL || isReadOnlyPkg(pkgId) != *isReadOnly) {
+ return -1;
+ }
+
ret = pkgmgrinfo_appinfo_get_root_path(handle, &root);
if (ret != PMINFO_R_OK) {
_SERR("Failed to get root path");
"INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \
"VALUES (%Q, %Q, %Q, %Q);", pkgId, nuget.c_str(), name.c_str(), version.c_str());
insertDB(tac_db, sql);
- restore_nuget.push_back(concatPath(__DOTNET_DIR, nuget));
+ restore_nuget.push_back(concatPath(*isReadOnly ? __READ_ONLY_TAC_DIR : __DOTNET_DIR, nuget));
sqlite3_free(sql);
}
}
return 0;
}
-tac_error_e tac_restoreDB()
+tac_error_e tac_restoreDB(bool isReadonly)
{
- if (!removeFile(TAC_APP_LIST_RESTORE_DB)) {
- _SERR("Failed to remove of %s", TAC_APP_LIST_RESTORE_DB);
+ std::string tacRestoreDbPath = tacDBPath(isReadonly, TAC_APP_LIST_RESTORE_DB);
+ if (!removeFile(tacRestoreDbPath)) {
+ _SERR("Failed to remove of %s", tacRestoreDbPath.c_str());
return TAC_ERROR_UNKNOWN;
}
- std::string dbRestoreJournal = TAC_APP_LIST_RESTORE_DB + std::string("-journal");
+ std::string dbRestoreJournal = tacRestoreDbPath + std::string("-journal");
if (!removeFile(dbRestoreJournal)) {
_SERR("Failed to remove of %s", dbRestoreJournal.c_str());
return TAC_ERROR_UNKNOWN;
}
- tac_db = createDB(TAC_APP_LIST_RESTORE_DB, CREATE_TAC_DB_TABLE);
+ tac_db = createDB(tacRestoreDbPath, CREATE_TAC_DB_TABLE);
if (!tac_db) {
_SERR("Sqlite create error");
return TAC_ERROR_UNKNOWN;
return TAC_ERROR_UNKNOWN;
}
- ret = pkgmgrAppMDFilterForeach(handle, tac_restoreDBCb, NULL);
+ ret = pkgmgrAppMDFilterForeach(handle, tac_restoreDBCb, &isReadonly);
if (ret != 0) {
pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
return TAC_ERROR_UNKNOWN;
tac_db = NULL;
}
- if (!copyFile(TAC_APP_LIST_RESTORE_DB, TAC_APP_LIST_DB)) {
- _SERR("Failed to copy of %s", TAC_APP_LIST_DB);
+ std::string tacDbPath = tacDBPath(isReadonly, TAC_APP_LIST_DB);
+ if (!copyFile(tacRestoreDbPath, tacDbPath)) {
+ _SERR("Failed to copy of %s", tacDbPath.c_str());
return TAC_ERROR_UNKNOWN;
}
- if (!removeFile(TAC_APP_LIST_RESTORE_DB)) {
- _SERR("Failed to remove of %s", TAC_APP_LIST_RESTORE_DB);
+ if (!removeFile(tacRestoreDbPath)) {
+ _SERR("Failed to remove of %s", tacRestoreDbPath.c_str());
return TAC_ERROR_UNKNOWN;
}
- std::string dbJournal = TAC_APP_LIST_DB + std::string("-journal");
+ std::string dbJournal = tacDbPath + std::string("-journal");
if (!copyFile(dbRestoreJournal, dbJournal)) {
_SERR("Failed to copy of %s", dbJournal.c_str());
return TAC_ERROR_UNKNOWN;
return TAC_ERROR_UNKNOWN;
}
- cleanupDirectory();
+ cleanupDirectory(isReadonly);
return TAC_ERROR_NONE;
}
tac_error_e enableTACPackage(const std::string& pkgId)
{
+ std::string tacLocation = isReadOnlyPkg(pkgId) ? __READ_ONLY_TAC_DIR : __DOTNET_DIR;
std::string rootPath = getRootPath(pkgId);
if (rootPath.empty()) {
_SERR("Failed to get root path from [%s]", pkgId.c_str());
for (auto& npAssembly : depsJsonParser(rootPath, execName)) {
std::string nugetPackage = npAssembly.substr(0, npAssembly.rfind(':'));
std::string assemblyName = npAssembly.substr(npAssembly.rfind(':') + 1);
- std::string nugetPath = concatPath(__DOTNET_DIR, nugetPackage);
+ std::string nugetPath = concatPath(tacLocation, nugetPackage);
if (exist(nugetPath)) {
std::string originPath = concatPath(nugetPath, assemblyName);
if (exist(originPath)) {
char *pkgId = NULL;
char *root = NULL;
std::string rootPath;
+ bool *isReadOnly = (bool*)userData;
int ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgId);
if (ret != PMINFO_R_OK) {
return -1;
}
+ if (userData == NULL || isReadOnlyPkg(pkgId) != *isReadOnly) {
+ return -1;
+ }
+
ret = pkgmgrinfo_appinfo_get_root_path(handle, &root);
if (ret != PMINFO_R_OK) {
_SERR("Failed to get root path");
return 0;
}
-tac_error_e tlc_restoreDB()
+tac_error_e tlc_restoreDB(bool isReadonly)
{
- if (!removeFile(TLC_APP_LIST_RESTORE_DB)) {
- _SERR("Failed to remove of %s", TLC_APP_LIST_RESTORE_DB);
+ std::string tlcRestoreDbPath = tacDBPath(isReadonly, TLC_APP_LIST_RESTORE_DB);
+ if (!removeFile(tlcRestoreDbPath)) {
+ _SERR("Failed to remove of %s", tlcRestoreDbPath.c_str());
return TAC_ERROR_UNKNOWN;
}
- std::string dbRestoreJournal = TLC_APP_LIST_RESTORE_DB + std::string("-journal");
+ std::string dbRestoreJournal = tlcRestoreDbPath + std::string("-journal");
if (!removeFile(dbRestoreJournal)) {
_SERR("Failed to remove of %s", dbRestoreJournal.c_str());
return TAC_ERROR_UNKNOWN;
}
- tlc_db = createDB(TLC_APP_LIST_RESTORE_DB, CREATE_TLC_DB_TABLE);
+ tlc_db = createDB(tlcRestoreDbPath, CREATE_TLC_DB_TABLE);
if (!tlc_db) {
_SERR("Sqlite create error");
return TAC_ERROR_UNKNOWN;
return TAC_ERROR_UNKNOWN;
}
- ret = pkgmgrAppMDFilterForeach(handle, tlc_restoreDBCb, NULL);
+ ret = pkgmgrAppMDFilterForeach(handle, tlc_restoreDBCb, &isReadonly);
if (ret != 0) {
pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
return TAC_ERROR_UNKNOWN;
tlc_db = NULL;
}
- if (!copyFile(TLC_APP_LIST_RESTORE_DB, TLC_APP_LIST_DB)) {
- _SERR("Failed to copy of %s", TLC_APP_LIST_DB);
+ std::string tlcDbPath = tacDBPath(isReadonly, TLC_APP_LIST_DB);
+ if (!copyFile(tlcRestoreDbPath, tlcDbPath)) {
+ _SERR("Failed to copy of %s", tlcDbPath.c_str());
return TAC_ERROR_UNKNOWN;
}
- if (!removeFile(TLC_APP_LIST_RESTORE_DB)) {
- _SERR("Failed to remove of %s", TLC_APP_LIST_RESTORE_DB);
+ if (!removeFile(tlcRestoreDbPath)) {
+ _SERR("Failed to remove of %s", tlcRestoreDbPath.c_str());
return TAC_ERROR_UNKNOWN;
}
- std::string dbJournal = TLC_APP_LIST_DB + std::string("-journal");
+ std::string dbJournal = tlcDbPath + std::string("-journal");
if (!copyFile(dbRestoreJournal, dbJournal)) {
_SERR("Failed to copy of %s", dbJournal.c_str());
return TAC_ERROR_UNKNOWN;
}
};
- scanFilesInDirectory(TLC_LIBRARIES_DIR, convert, 0);
+ scanFilesInDirectory(tlcLBPath(isReadonly), convert, 0);
return TAC_ERROR_NONE;
}
#define __XSTR(x) #x
#define __STR(x) __XSTR(x)
static const char* __DOTNET_DIR = __STR(DOTNET_DIR);
+static const char* __READ_ONLY_TAC_DIR = __STR(READ_ONLY_TAC_DIR);
#undef __STR
#undef __XSTR
return 0;
}
-int tac_createDB()
+int tac_createDB(bool isReadonly)
{
- tac_db = createDB(TAC_APP_LIST_DB, CREATE_TAC_DB_TABLE);
+ std::string tacDbPath = tacDBPath(isReadonly, TAC_APP_LIST_DB);
+ tac_db = createDB(tacDbPath, CREATE_TAC_DB_TABLE);
if (!tac_db) {
_ERR("Sqlite create error. So restore the database.");
- if (tac_restoreDB() != TAC_ERROR_NONE) {
+ if (tac_restoreDB(isReadonly) != TAC_ERROR_NONE) {
_ERR("Sqlite create error");
return -1;
}
- tac_db = createDB(TAC_APP_LIST_DB, CREATE_TAC_DB_TABLE);
+ tac_db = createDB(tacDbPath, CREATE_TAC_DB_TABLE);
if (!tac_db) {
_ERR("Sqlite create error");
return -1;
return 0;
}
-int tac_openDB()
+int tac_openDB(bool isReadonly)
{
- tac_db = openDB(TAC_APP_LIST_DB);
+ std::string tacDbPath = tacDBPath(isReadonly, TAC_APP_LIST_DB);
+ tac_db = openDB(tacDbPath);
if (!tac_db) {
_ERR("Sqlite open error. So restore the database.");
- if (tac_restoreDB() != TAC_ERROR_NONE) {
+ if (tac_restoreDB(isReadonly) != TAC_ERROR_NONE) {
_ERR("Sqlite open error");
return -1;
}
- tac_db = openDB(TAC_APP_LIST_DB);
+ tac_db = openDB(tacDbPath);
if (!tac_db) {
_ERR("Sqlite open error");
return -1;
return false;
}
-int tlc_createDB()
+int tlc_createDB(bool isReadonly)
{
- if (!createDir(TLC_LIBRARIES_DIR)) {
- _ERR("Cannot create directory: %s", TLC_LIBRARIES_DIR);
+ std::string tlcPath = tlcLBPath(isReadonly);
+ if (!createDir(tlcPath)) {
+ _ERR("Cannot create directory: %s", tlcPath.c_str());
return -1;
}
- copySmackAndOwnership(__DOTNET_DIR, TLC_LIBRARIES_DIR);
+ std::string tacLocation = isReadonly ? __READ_ONLY_TAC_DIR : __DOTNET_DIR;
+ copySmackAndOwnership(tacLocation, tlcPath);
- tlc_db = createDB(TLC_APP_LIST_DB, CREATE_TLC_DB_TABLE);
+ std::string tlcDbPath = tacDBPath(isReadonly, TLC_APP_LIST_DB);
+ tlc_db = createDB(tlcDbPath, CREATE_TLC_DB_TABLE);
if (!tlc_db) {
_ERR("Sqlite create error. So restore the database.");
- if (tlc_restoreDB() != TAC_ERROR_NONE) {
+ if (tlc_restoreDB(isReadonly) != TAC_ERROR_NONE) {
_ERR("Sqlite create error");
return -1;
}
- tlc_db = createDB(TLC_APP_LIST_DB, CREATE_TLC_DB_TABLE);
+ tlc_db = createDB(tlcDbPath, CREATE_TLC_DB_TABLE);
if (!tlc_db) {
_ERR("Sqlite create error");
return -1;
return 0;
}
-int tlc_openDB()
+int tlc_openDB(bool isReadonly)
{
- tlc_db = openDB(TLC_APP_LIST_DB);
+ std::string tlcDbPath = tacDBPath(isReadonly, TLC_APP_LIST_DB);
+ tlc_db = openDB(tlcDbPath);
if (!tlc_db) {
_ERR("Sqlite open error. So restore the database.");
- if (tlc_restoreDB() != TAC_ERROR_NONE) {
+ if (tlc_restoreDB(isReadonly) != TAC_ERROR_NONE) {
_ERR("Sqlite open error");
return 0;
}
- tlc_db = openDB(TLC_APP_LIST_DB);
+ tlc_db = openDB(tlcDbPath);
if (!tlc_db) {
_ERR("Sqlite open error");
return 0;
#define __XSTR(x) #x
#define __STR(x) __XSTR(x)
static const char* __DOTNET_DIR = __STR(DOTNET_DIR);
+static const char* __READ_ONLY_TAC_DIR = __STR(READ_ONLY_TAC_DIR);
#undef __STR
#undef __XSTR
static tac_state tacState = TAC_STATE_NONE;
static std::string prevInstallPkgId = std::string("");
static std::string prevFinishPkgId = std::string("");
+static std::string tacLocation = __DOTNET_DIR;
+static bool isTacReadonly = false;
// initialize static vector to support multi-package install scenario
static void tacInitialize()
static bool copyAssemblyCreateSymlink(std::string binPath, std::string tacDir, std::string nugetPackage, bool isCreateTacDir)
{
std::string binNiPath = concatPath(binPath, APP_NI_SUB_DIR);
- std::string tac_version_dir = concatPath(__DOTNET_DIR, nugetPackage);
+ std::string tac_version_dir = concatPath(tacLocation, nugetPackage);
bool nuget_restoration = false;
for (auto& npAssemblySha : nugetPackagesAssembliesSha) {
std::string nuget_package_assembly = npAssemblySha.substr(0, npAssemblySha.rfind(':'));
std::string library = librarySha.substr(0, librarySha.find(':'));
std::string filename = library.substr(library.rfind('/') + 1);
std::string fileSha = filename + ".." + librarySha.substr(librarySha.find(':') + 1);
- std::string shaPath = concatPath(TLC_LIBRARIES_DIR, fileSha);
+ std::string shaPath = concatPath(tlcLBPath(isTacReadonly), fileSha);
bool fileCopied = false;
if (!exist(shaPath)) {
if (!copyFile(library, shaPath)) {
_INFO("TAC version : %s", tac_version.c_str());
bs::error_code error;
- std::string tac_version_dir = concatPath(__DOTNET_DIR, np);
+ std::string tac_version_dir = concatPath(tacLocation, np);
std::string sha256_info = concatPath(tac_version_dir, TAC_SHA_256_INFO);
bool isCreateTacDir = false;
if (!exist(tac_version_dir)) {
}
if (count == 0) {
- std::string tac_version_dir_prev = concatPath(__DOTNET_DIR, unp);
+ std::string tac_version_dir_prev = concatPath(tacLocation, unp);
std::string tac_version_dir_backup = tac_version_dir_prev + ".bck";
if (!copyDir(tac_version_dir_prev, tac_version_dir_backup)) {
_ERR("Failed to copy of %s to %s", tac_version_dir_prev.c_str(), tac_version_dir_backup.c_str());
}
if (count == 0) {
- std::string library_prev = concatPath(TLC_LIBRARIES_DIR, ulp);
+ std::string library_prev = concatPath(tlcLBPath(isTacReadonly), ulp);
std::string library_backup = library_prev + ".bck";
if (!copyFile(library_prev, library_backup)) {
_ERR("Failed to copy of %s", library_prev.c_str());
tacInitialize();
+ isTacReadonly = isReadOnlyPkg(pkgId);
+ tacLocation = isTacReadonly ? __READ_ONLY_TAC_DIR : __DOTNET_DIR;
+
// Can be multiple apps in one package
if (strcmp(pkgId.c_str(), prevInstallPkgId.c_str()) == 0) {
_INFO("TAC Plugin(INSTALL) already run for same pkgId (%s)", pkgId.c_str());
return 0;
}
- if (tac_createDB() != 0) {
+ if (tac_createDB(isTacReadonly) != 0) {
return -1;
}
}
///// TLC /////
- if (tlc_createDB() != 0) {
+ if (tlc_createDB(isTacReadonly) != 0) {
tac_closeDB();
return -1;
}
tacInitialize();
+ isTacReadonly = isReadOnlyPkg(pkgId);
+ tacLocation = isTacReadonly ? __READ_ONLY_TAC_DIR : __DOTNET_DIR;
+
// Can be multiple apps in one package
if (strcmp(pkgId.c_str(), prevInstallPkgId.c_str()) == 0) {
_INFO("TAC Plugin(UPGRADE) already run for same pkgId (%s)", pkgId.c_str());
}
tacState = TAC_STATE_UPGRADE;
- if (tac_createDB() != 0) {
+ if (tac_createDB(isTacReadonly) != 0) {
return -1;
}
}
///// TLC /////
- if (tlc_createDB() != 0) {
+ if (tlc_createDB(isTacReadonly) != 0) {
tac_closeDB();
return -1;
}
tacInitialize();
+ isTacReadonly = isReadOnlyPkg(pkgId);
+ tacLocation = isTacReadonly ? __READ_ONLY_TAC_DIR : __DOTNET_DIR;
+
// Can be multiple apps in one package
if (strcmp(pkgId.c_str(), prevInstallPkgId.c_str()) == 0) {
_INFO("TAC Plugin(UNINSTALL) already run for same pkgId (%s)", pkgId.c_str());
prevInstallPkgId = pkgId;
tacState= state;
- if (tac_openDB() != 0) {
+ if (tac_openDB(isTacReadonly) != 0) {
return -1;
}
tacUpdateDB(pkgId);
///// TLC /////
- if (tlc_openDB() != 0) {
+ if (tlc_openDB(isTacReadonly) != 0) {
tac_closeDB();
return -1;
}
void undoStep(std::string tac)
{
- std::string current_tac = concatPath(__DOTNET_DIR, tac.substr(0, tac.find('/')));
+ std::string current_tac = concatPath(tacLocation, tac.substr(0, tac.find('/')));
try {
for (auto& bck : bf::recursive_directory_iterator(current_tac)) {
std::string bck_path = bck.path().string();
}
};
- scanFilesInDirectory(TLC_LIBRARIES_DIR, convert, 0);
+ scanFilesInDirectory(tlcLBPath(isTacReadonly), convert, 0);
}
void install_Undo()
_DBG("[===== PKGMGR_MDPARSER_PLUGIN_UNDO =====]");
_INFO("PackageID : %s", pkgId.c_str());
+ isTacReadonly = isReadOnlyPkg(pkgId);
+ tacLocation = isTacReadonly ? __READ_ONLY_TAC_DIR : __DOTNET_DIR;
+
// Can be multiple apps in one package
if (strcmp(pkgId.c_str(), prevFinishPkgId.c_str()) == 0) {
_INFO("TAC Plugin(UNDO) already run for same pkgId (%s)", pkgId.c_str());
void changeOwnershipTAC(std::string current_tac)
{
- copySmackAndOwnership(__DOTNET_DIR, current_tac);
+ copySmackAndOwnership(tacLocation, current_tac);
try {
for (auto& path : bf::recursive_directory_iterator(current_tac))
- copySmackAndOwnership(__DOTNET_DIR, path.path().string());
+ copySmackAndOwnership(tacLocation, path.path().string());
} catch (const bf::filesystem_error& error) {
_ERR("Failed to recursive directory: %s", error.what());
}
void cleanStep(std::string tac)
{
- std::string current_tac = concatPath(__DOTNET_DIR, tac.substr(0, tac.find('/')));
+ std::string current_tac = concatPath(tacLocation, tac.substr(0, tac.find('/')));
try {
for (auto& bck : bf::recursive_directory_iterator(current_tac)) {
std::string bck_path = bck.path().string();
}
};
- scanFilesInDirectory(TLC_LIBRARIES_DIR, convert, 0);
+ scanFilesInDirectory(tlcLBPath(isTacReadonly), convert, 0);
}
void install_Clean()
{
for (auto& cd : createDirectories) {
changeOwnershipTAC(cd);
- copySmackAndOwnership(__DOTNET_DIR, cd.substr(0, cd.rfind('/')));
+ copySmackAndOwnership(tacLocation, cd.substr(0, cd.rfind('/')));
}
for (auto& cl : createLibraries) {
- copySmackAndOwnership(__DOTNET_DIR, cl);
+ copySmackAndOwnership(tacLocation, cl);
}
}
if (!tacDB.empty()) {
for (auto& np : tacDB) {
cleanStep(np);
- changeOwnershipTAC(concatPath(__DOTNET_DIR, np.substr(0, np.find('/'))));
+ changeOwnershipTAC(concatPath(tacLocation, np.substr(0, np.find('/'))));
}
}
unInstall_Clean();
}
if (tac_closeDB()) {
- copySmackAndOwnership(__DOTNET_DIR, TAC_APP_LIST_DB);
- copySmackAndOwnership(__DOTNET_DIR, TAC_APP_LIST_DB + std::string("-journal"));
+ std::string tacDbPath = tacDBPath(isTacReadonly, TAC_APP_LIST_DB);
+ copySmackAndOwnership(tacLocation, tacDbPath);
+ copySmackAndOwnership(tacLocation, tacDbPath + std::string("-journal"));
}
if (tlc_closeDB()) {
- copySmackAndOwnership(__DOTNET_DIR, TLC_APP_LIST_DB);
- copySmackAndOwnership(__DOTNET_DIR, TLC_APP_LIST_DB + std::string("-journal"));
+ std::string tlcDbPath = tacDBPath(isTacReadonly, TLC_APP_LIST_DB);
+ copySmackAndOwnership(tacLocation, tlcDbPath);
+ copySmackAndOwnership(tacLocation, tlcDbPath + std::string("-journal"));
}
return 0;
#include "path_manager.h"
#include "r2r_checker.h"
+#define __XSTR(x) #x
+#define __STR(x) __XSTR(x)
+static const char* __DOTNET_DIR = __STR(DOTNET_DIR);
+static const char* __READ_ONLY_TAC_DIR = __STR(READ_ONLY_TAC_DIR);
+#undef __STR
+#undef __XSTR
+
static bool iCompare(const std::string& a, int aOffset, const std::string& b, int bOffset, int length)
{
return static_cast<int>(a.length()) - length >= aOffset &&
}
+bool isReadOnlyPkg(const std::string& pkgId)
+{
+ uid_t uid = 0;
+ int ret = 0;
+ bool readonly = false;
+ pkgmgrinfo_pkginfo_h handle;
+
+ if (pkgmgr_installer_info_get_target_uid(&uid) < 0) {
+ _ERR("Failed to get UID");
+ return false;
+ }
+
+ ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId.c_str(), uid, &handle);
+ if (ret != PMINFO_R_OK) {
+ _ERR("Fail to get pkginfo");
+ return false;
+ }
+
+ ret = pkgmgrinfo_pkginfo_is_readonly(handle, &readonly);
+ if (ret != PMINFO_R_OK) {
+ _ERR("Fail to get is_readonly");
+ pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+ return false;
+ }
+
+ pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+ return readonly;
+}
+
+std::string tacDBPath(bool isReadonly, const std::string& dbName)
+{
+ return isReadonly ? concatPath(__READ_ONLY_TAC_DIR, dbName) : concatPath(__DOTNET_DIR, dbName);
+}
+
+std::string tlcLBPath(bool isReadonly)
+{
+ return isReadonly ? concatPath(__READ_ONLY_TAC_DIR, TLC_LIBRARIES_DIR) : concatPath(__DOTNET_DIR, TLC_LIBRARIES_DIR);
+}
+
std::string getBaseName(const std::string& path)
{
auto pos = path.find_last_of(PATH_SEPARATOR);
</request>
<assign>
<filesystem path="/opt/usr/dotnet" label="System::Shared" type="transmutable" />
+ <filesystem path="/usr/share/dotnet.tizen/tac" label="System::Shared" type="transmutable" />
<filesystem path="/opt/usr/dotnet/apps" label="User::Home"/>
<filesystem path="/usr/bin/dotnet-loader" label="User" exec_label="User" />
<filesystem path="/usr/bin/dotnet-hydra-loader" label="User" exec_label="User" />
%define _native_lib_dir /usr/share/dotnet.tizen/lib
%define _dotnet_dir /opt/usr/dotnet
%define _readonly_app_update_dir /opt/usr/dotnet/apps
+%define _readonly_tac_dir /usr/share/dotnet.tizen/tac
%define _system_base_addr_file /opt/usr/dotnet.system.base.addr
%define _tizen_preload_dir /usr/share/dotnet.tizen/preload
-DINSTALL_PLUGIN_DIR=%{_install_plugin_dir} \
-DDOTNET_DIR=%{_dotnet_dir} \
-DREAD_ONLY_APP_UPDATE_DIR=%{_readonly_app_update_dir} \
+ -DREAD_ONLY_TAC_DIR=%{_readonly_tac_dir} \
-DVERSION=%{version} \
-DNATIVE_LIB_DIR=%{_native_lib_dir} \
%ifarch %{arm} aarch64
mkdir -p %{buildroot}%{_dotnet_dir}
mkdir -p %{buildroot}%{_readonly_app_update_dir}
+mkdir -p %{buildroot}%{_readonly_tac_dir}
mkdir -p %{buildroot}%{_native_lib_dir}
ln -sf %{_libdir}/libsqlite3.so.0 %{buildroot}%{_native_lib_dir}/libsqlite3.so
%{_framework_dir}/Tizen.Runtime.dll
%{_dotnet_dir}
%{_readonly_app_update_dir}
+%{_readonly_tac_dir}
%{_tizen_preload_dir}
%{_rw_update_scripts_dir}/%{_rw_dotnet_update_script}
%if 0%{_build_dotnet_plugin}
--- /dev/null
+#!/usr/bin/env python3
+import os, subprocess, sys, argparse
+sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
+
+from time import sleep
+from Utils import *
+
+
+module_name = "TAC"
+
+# The `Launcher_TC_TAC_01` application must have TAC applied.
+def TC_01():
+ sln_name = "Launcher_TC_TAC_01.Tizen"
+
+ tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
+ if tpk_path == None:
+ return f"FAIL : Get the tpk path for {sln_name}"
+
+ raw = cmd(f"push {tpk_path} /usr/apps/.preload-tpk/")
+ if "1 file(s) pushed. 0 file(s) skipped." in raw:
+ cmd(f"shell install_preload_pkg")
+
+ pkg_id = f"org.tizen.example.Launcher_TC_TAC_01.Tizen"
+
+ root_path = get_root_path(f"{pkg_id}")
+ if root_path == "None":
+ return f"FAIL : Get the root path for {pkg_id}"
+
+ if not exist(f"{root_path}/bin/.tac_symlink"):
+ return "FAIL : The .tac_symlink folder should exist"
+
+ raw = cmd(f"shell find {root_path}/bin/.tac_symlink/ -name *.dll -not -name *.ni.dll")
+ lines1 = [l for l in raw.splitlines()]
+ raw = cmd(f"shell find {RO_TAC_DIR}Xamarin.Forms/4.6.0.967/ -name *.dll -not -name *.ni.dll")
+ lines2 = [l for l in raw.splitlines()]
+ if len(lines1) != len(lines2):
+ return "FAIL : The number of .dll in the .tac_symlink and .dll in the TAC must match"
+
+ raw = cmd(f"shell ls -alZ {root_path}/bin/.tac_symlink/*.dll")
+ lines = [l for l in raw.splitlines() if ".ni.dll" not in l]
+ for dll in lines:
+ origin_path = dll.split("->")[1].strip()
+ if not exist(f"{origin_path}"):
+ return "FAIL : The original file of the symbolic link must exist"
+
+ pid = launch_and_get_pid(f"-e", f"{pkg_id}")
+ if 0 == pid:
+ return f"FAIL : Get the pid for {pkg_id}"
+
+ raw = cmd(f"shell cat /proc/{pid}/smaps | grep Xamarin.Forms.*.dll")
+ if (f"{RO_TAC_DIR}Xamarin.Forms/4.6.0.967/Xamarin.Forms.Platform.Tizen.dll" not in raw) or \
+ (f"{RO_TAC_DIR}Xamarin.Forms/4.6.0.967/Xamarin.Forms.Core.dll" not in raw) or \
+ (f"{RO_TAC_DIR}Xamarin.Forms/4.6.0.967/Xamarin.Forms.Platform.dll" not in raw):
+ return "FAIL : The Xamarin.Forms in the TAC should be loaded when running the application"
+
+ cmd(f"shell app_launcher -t {pkg_id}")
+
+ return "PASS"
+
+# The `Launcher_TC_TAC_02` application must have TAC applied.
+def TC_02():
+ sln_name = "Launcher_TC_TAC_02.Tizen"
+
+ tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
+ if tpk_path == None:
+ return f"FAIL : Get the tpk path for {sln_name}"
+
+ raw = cmd(f"push {tpk_path} /usr/apps/.preload-tpk/")
+ if "1 file(s) pushed. 0 file(s) skipped." in raw:
+ cmd(f"shell install_preload_pkg")
+
+ pkg_id = f"org.tizen.example.Launcher_TC_TAC_00.Tizen"
+
+ root_path = get_root_path(f"{pkg_id}")
+ if root_path == "None":
+ return f"FAIL : Get the root path for {pkg_id}"
+
+ if not exist(f"{root_path}/bin/.tac_symlink"):
+ return "FAIL : The .tac_symlink folder should exist"
+
+ raw = cmd(f"shell find {root_path}/bin/.tac_symlink/ -name *.dll -not -name *.ni.dll")
+ lines1 = [l for l in raw.splitlines()]
+ raw = cmd(f"shell find {RO_TAC_DIR}Xamarin.Forms/4.8.0.1364/ -name *.dll -not -name *.ni.dll")
+ lines2 = [l for l in raw.splitlines()]
+ raw = cmd(f"shell find {RO_TAC_DIR}Newtonsoft.Json/13.0.1/ -name *.dll -not -name *.ni.dll")
+ lines3 = [l for l in raw.splitlines()]
+ if len(lines1) != len(lines2)+len(lines3):
+ return "FAIL : The number of .dll in the .tac_symlink and .dll in the TAC must match"
+
+ raw = cmd(f"shell ls -alZ {root_path}/bin/.tac_symlink/*.dll")
+ lines = [l for l in raw.splitlines() if ".ni.dll" not in l]
+ for dll in lines:
+ origin_path = dll.split("->")[1].strip()
+ if not exist(f"{origin_path}"):
+ return "FAIL : The original file of the symbolic link must exist"
+
+ pid = launch_and_get_pid(f"-e", f"{pkg_id}")
+ if 0 == pid:
+ return f"FAIL : Get the pid for {pkg_id}"
+
+ raw = cmd(f"shell cat /proc/{pid}/smaps | grep Xamarin.Forms.*.dll")
+ if (f"{RO_TAC_DIR}Xamarin.Forms/4.8.0.1364/Xamarin.Forms.Platform.Tizen.dll" not in raw) or \
+ (f"{RO_TAC_DIR}Xamarin.Forms/4.8.0.1364/Xamarin.Forms.Core.dll" not in raw) or \
+ (f"{RO_TAC_DIR}Xamarin.Forms/4.8.0.1364/Xamarin.Forms.Platform.dll" not in raw):
+ return "FAIL : The Xamarin.Forms in the TAC should be loaded when running the application"
+
+ raw = cmd(f"shell cat /proc/{pid}/smaps | grep Newtonsoft.Json.dll")
+ if f"{RO_TAC_DIR}Newtonsoft.Json/13.0.1/Newtonsoft.Json.dll" not in raw:
+ return "FAIL : The Newtonsoft.Json in the TAC should be loaded when running the application"
+
+ cmd(f"shell app_launcher -t {pkg_id}")
+
+ return "PASS"
+
+# The `Launcher_TC_TAC_03` application is normally TAC applied when updating.
+def TC_03():
+ sln_name = "Launcher_TC_TAC_03.Tizen"
+
+ tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
+ if tpk_path == None:
+ return f"FAIL : Get the tpk path for {sln_name}"
+
+ raw = cmd(f"push {tpk_path} /usr/apps/.preload-tpk/")
+ if "1 file(s) pushed. 0 file(s) skipped." in raw:
+ cmd(f"shell install_preload_pkg")
+
+ pkg_id = f"org.tizen.example.Launcher_TC_TAC_00.Tizen"
+
+ root_path = get_root_path(f"{pkg_id}")
+ if root_path == "None":
+ return f"FAIL : Get the root path for {pkg_id}"
+
+ if not exist(f"{root_path}/bin/.tac_symlink"):
+ return "FAIL : The .tac_symlink folder should exist"
+
+ raw = cmd(f"shell find {root_path}/bin/.tac_symlink/ -name *.dll -not -name *.ni.dll")
+ lines1 = [l for l in raw.splitlines()]
+ raw = cmd(f"shell find {RO_TAC_DIR}Xamarin.Forms/4.8.0.1687/ -name *.dll -not -name *.ni.dll")
+ lines2 = [l for l in raw.splitlines()]
+ raw = cmd(f"shell find {RO_TAC_DIR}sqlite-net-base/1.7.335/ -name *.dll -not -name *.ni.dll")
+ lines3 = [l for l in raw.splitlines()]
+ raw = cmd(f"shell find {RO_TAC_DIR}SQLitePCLRaw.core/2.0.3/ -name *.dll -not -name *.ni.dll")
+ lines4 = [l for l in raw.splitlines()]
+ if len(lines1) != len(lines2)+len(lines3)+len(lines4):
+ return "FAIL : The number of .dll in the .tac_symlink and .dll in the TAC must match"
+
+ raw = cmd(f"shell ls -alZ {root_path}/bin/.tac_symlink/*.dll")
+ lines = [l for l in raw.splitlines() if ".ni.dll" not in l]
+ for dll in lines:
+ origin_path = dll.split("->")[1].strip()
+ if not exist(f"{origin_path}"):
+ return "FAIL : The original file of the symbolic link must exist"
+
+ if exist(f"{RO_TAC_DIR}Xamarin.Forms/4.8.0.1364/ -name *.dll"):
+ return f"FAIL : The Xamarin.Forms/4.8.0.1364 nuget should not exist in {RO_TAC_DIR}"
+
+ if exist(f"{RO_TAC_DIR}Newtonsoft.Json/13.0.1/ -name *.dll"):
+ return f"FAIL : The Newtonsoft.Json/13.0.1 nuget should not exist in {RO_TAC_DIR}"
+
+ pid = launch_and_get_pid(f"-e", f"{pkg_id}")
+ if 0 == pid:
+ return f"FAIL : Get the pid for {pkg_id}"
+
+ raw = cmd(f"shell cat /proc/{pid}/smaps | grep Xamarin.Forms.*.dll")
+ if (f"{RO_TAC_DIR}Xamarin.Forms/4.8.0.1687/Xamarin.Forms.Platform.Tizen.dll" not in raw) or \
+ (f"{RO_TAC_DIR}Xamarin.Forms/4.8.0.1687/Xamarin.Forms.Core.dll" not in raw) or \
+ (f"{RO_TAC_DIR}Xamarin.Forms/4.8.0.1687/Xamarin.Forms.Platform.dll" not in raw):
+ return "FAIL : The Xamarin.Forms in the TAC should be loaded when running the application"
+
+ raw = cmd(f"shell cat /proc/{pid}/smaps | grep SQLite-net.dll")
+ if f"{RO_TAC_DIR}sqlite-net-base/1.7.335/SQLite-net.dll" not in raw:
+ return "FAIL : The sqlite-net-base in the TAC should be loaded when running the application"
+
+ raw = cmd(f"shell cat /proc/{pid}/smaps | grep SQLitePCLRaw.core.dll")
+ if f"{RO_TAC_DIR}SQLitePCLRaw.core/2.0.3/SQLitePCLRaw.core.dll" not in raw:
+ return "FAIL : The SQLitePCLRaw.core in the TAC should be loaded when running the application"
+
+ cmd(f"shell app_launcher -t {pkg_id}")
+
+ return "PASS"
+
+# The `Launcher_TC_TAC_04` application should not apply TAC when updating.
+def TC_04():
+ sln_name = "Launcher_TC_TAC_04.Tizen"
+
+ tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
+ if tpk_path == None:
+ return f"FAIL : Get the tpk path for {sln_name}"
+
+ raw = cmd(f"push {tpk_path} /usr/apps/.preload-tpk/")
+ if "1 file(s) pushed. 0 file(s) skipped." in raw:
+ cmd(f"shell install_preload_pkg")
+
+ pkg_id = f"org.tizen.example.Launcher_TC_TAC_00.Tizen"
+
+ root_path = get_root_path(f"{pkg_id}")
+ if root_path == "None":
+ return f"FAIL : Get the root path for {pkg_id}"
+
+ if exist(f"{root_path}/bin/.tac_symlink"):
+ return "FAIL : The .tac_symlink folder should not exist"
+
+ if exist(f"{RO_TAC_DIR}Xamarin.Forms/4.8.0.1364/ -name *.dll"):
+ return f"FAIL : The Xamarin.Forms/4.8.0.1364 nuget should not exist in {RO_TAC_DIR}"
+
+ if exist(f"{RO_TAC_DIR}Newtonsoft.Json/13.0.1/ -name *.dll"):
+ return f"FAIL : The Newtonsoft.Json/13.0.1 nuget should not exist in {RO_TAC_DIR}"
+
+ if exist(f"{RO_TAC_DIR}sqlite-net-base/1.7.335/ -name *.dll"):
+ return f"FAIL : The sqlite-net-base/1.7.335 nuget should not exist in {RO_TAC_DIR}"
+
+ if exist(f"{RO_TAC_DIR}SQLitePCLRaw.core/2.0.3/ -name *.dll"):
+ return f"FAIL : The SQLitePCLRaw.core/2.0.3 nuget should not exist in {RO_TAC_DIR}"
+
+ pid = launch_and_get_pid(f"-e", f"{pkg_id}")
+ if 0 == pid:
+ return f"FAIL : Get the pid for {pkg_id}"
+
+ raw = cmd(f"shell cat /proc/{pid}/smaps | grep Xamarin.Forms.*.dll")
+ if (f"{root_path}/bin/Xamarin.Forms.Platform.Tizen.dll" not in raw) or \
+ (f"{root_path}/bin/Xamarin.Forms.Core.dll" not in raw) or \
+ (f"{root_path}/bin/Xamarin.Forms.Platform.dll" not in raw):
+ return "FAIL : The Xamarin.Forms in the application should be loaded when running the application"
+
+ cmd(f"shell app_launcher -t {pkg_id}")
+
+ return "PASS"
+
+# The `Launcher_TC_TAC_05`, `Launcher_TC_TAC_06` applications using the same nuget are normally TAC applied.
+def TC_05():
+ sln_name = "Launcher_TC_TAC_05.Tizen"
+
+ tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
+ if tpk_path == None:
+ return f"FAIL : Get the tpk path for {sln_name}"
+
+ raw = cmd(f"push {tpk_path} /usr/apps/.preload-tpk/")
+ if "1 file(s) pushed. 0 file(s) skipped." in raw:
+ cmd(f"shell install_preload_pkg")
+
+ pkg_id1 = f"org.tizen.example.Launcher_TC_TAC_05.Tizen"
+
+ root_path = get_root_path(f"{pkg_id1}")
+ if root_path == "None":
+ return f"FAIL : Get the root path for {pkg_id1}"
+
+ if not exist(f"{root_path}/bin/.tac_symlink"):
+ return "FAIL : The .tac_symlink folder should exist"
+
+ raw = cmd(f"shell find {root_path}/bin/.tac_symlink/ -name *.dll -not -name *.ni.dll")
+ lines1 = [l for l in raw.splitlines()]
+ raw = cmd(f"shell find {RO_TAC_DIR}Xamarin.Forms/5.0.0.1558-pre3/ -name *.dll -not -name *.ni.dll")
+ lines2 = [l for l in raw.splitlines()]
+ if len(lines1) != len(lines2):
+ return "FAIL : The number of .dll in the .tac_symlink and .dll in the TAC must match"
+
+ raw = cmd(f"shell ls -alZ {root_path}/bin/.tac_symlink/*.dll")
+ lines = [l for l in raw.splitlines() if ".ni.dll" not in l]
+ for dll in lines:
+ origin_path = dll.split("->")[1].strip()
+ if not exist(f"{origin_path}"):
+ return "FAIL : The original file of the symbolic link must exist"
+
+ sln_name = "Launcher_TC_TAC_06.Tizen"
+
+ tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
+ if tpk_path == None:
+ return f"FAIL : Get the tpk path for {sln_name}"
+
+ raw = cmd(f"push {tpk_path} /usr/apps/.preload-tpk/")
+ if "1 file(s) pushed. 0 file(s) skipped." in raw:
+ cmd(f"shell install_preload_pkg")
+
+ pkg_id2 = f"org.tizen.example.Launcher_TC_TAC_06.Tizen"
+
+ root_path = get_root_path(f"{pkg_id2}")
+ if root_path == "None":
+ return f"FAIL : Get the root path for {pkg_id2}"
+
+ if not exist(f"{root_path}/bin/.tac_symlink"):
+ return "FAIL : The .tac_symlink folder should exist"
+
+ raw = cmd(f"shell find {root_path}/bin/.tac_symlink/ -name *.dll -not -name *.ni.dll")
+ lines1 = [l for l in raw.splitlines()]
+ raw = cmd(f"shell find {RO_TAC_DIR}Xamarin.Forms/5.0.0.1558-pre3/ -name *.dll -not -name *.ni.dll")
+ lines2 = [l for l in raw.splitlines()]
+ if len(lines1) != len(lines2):
+ return "FAIL : The number of .dll in the .tac_symlink and .dll in the TAC must match"
+
+ raw = cmd(f"shell ls -alZ {root_path}/bin/.tac_symlink/*.dll")
+ lines = [l for l in raw.splitlines() if ".ni.dll" not in l]
+ for dll in lines:
+ origin_path = dll.split("->")[1].strip()
+ if not exist(f"{origin_path}"):
+ return "FAIL : The original file of the symbolic link must exist"
+
+ cmd(f"shell tpk-backend --force-remove --preload -d {pkg_id1}")
+
+ raw = cmd(f"shell find {root_path}/bin/.tac_symlink/ -name *.dll -not -name *.ni.dll")
+ lines1 = [l for l in raw.splitlines()]
+ raw = cmd(f"shell find {RO_TAC_DIR}Xamarin.Forms/5.0.0.1558-pre3/ -name *.dll -not -name *.ni.dll")
+ lines2 = [l for l in raw.splitlines()]
+ if len(lines1) != len(lines2):
+ return "FAIL : The number of .dll in the .tac_symlink and .dll in the TAC must match"
+
+ raw = cmd(f"shell ls -alZ {root_path}/bin/.tac_symlink/*.dll")
+ lines = [l for l in raw.splitlines() if ".ni.dll" not in l]
+ for dll in lines:
+ origin_path = dll.split("->")[1].strip()
+ if not exist(f"{origin_path}"):
+ return "FAIL : The original file of the symbolic link must exist"
+
+ pid = launch_and_get_pid(f"-e", f"{pkg_id2}")
+ if 0 == pid:
+ return f"FAIL : Get the pid for {pkg_id2}"
+
+ raw = cmd(f"shell cat /proc/{pid}/smaps | grep Xamarin.Forms.*.dll")
+ if (f"{RO_TAC_DIR}Xamarin.Forms/5.0.0.1558-pre3/Xamarin.Forms.Platform.Tizen.dll" not in raw) or \
+ (f"{RO_TAC_DIR}Xamarin.Forms/5.0.0.1558-pre3/Xamarin.Forms.Core.dll" not in raw) or \
+ (f"{RO_TAC_DIR}Xamarin.Forms/5.0.0.1558-pre3/Xamarin.Forms.Platform.dll" not in raw):
+ return "FAIL : The Xamarin.Forms in the TAC should be loaded when running the application"
+
+ cmd(f"shell app_launcher -t {pkg_id2}")
+
+ return "PASS"
+
+# The `Launcher_TC_TAC_07` application is normally TAC applied when uninstall.
+def TC_06():
+ sln_name = "Launcher_TC_TAC_07.Tizen"
+
+ tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
+ if tpk_path == None:
+ return f"FAIL : Get the tpk path for {sln_name}"
+
+ raw = cmd(f"push {tpk_path} /usr/apps/.preload-tpk/")
+ if "1 file(s) pushed. 0 file(s) skipped." in raw:
+ cmd(f"shell install_preload_pkg")
+
+ pkg_id = f"org.tizen.example.Launcher_TC_TAC_07.Tizen"
+
+ root_path = get_root_path(f"{pkg_id}")
+ if root_path == "None":
+ return f"FAIL : Get the root path for {pkg_id}"
+
+ if not exist(f"{root_path}/bin/.tac_symlink"):
+ return "FAIL : The .tac_symlink folder should exist"
+
+ raw = cmd(f"shell find {root_path}/bin/.tac_symlink/ -name *.dll -not -name *.ni.dll")
+ lines1 = [l for l in raw.splitlines()]
+ raw = cmd(f"shell find {RO_TAC_DIR}Xamarin.Forms/4.4.0.991864/ -name *.dll -not -name *.ni.dll")
+ lines2 = [l for l in raw.splitlines()]
+ if len(lines1) != len(lines2):
+ return "FAIL : The number of .dll in the .tac_symlink and .dll in the TAC must match"
+
+ raw = cmd(f"shell ls -alZ {root_path}/bin/.tac_symlink/*.dll")
+ lines = [l for l in raw.splitlines() if ".ni.dll" not in l]
+ for dll in lines:
+ origin_path = dll.split("->")[1].strip()
+ if not exist(f"{origin_path}"):
+ return "FAIL : The original file of the symbolic link must exist"
+
+ cmd(f"shell tpk-backend --force-remove --preload -d {pkg_id}")
+
+ if exist(f"{RO_TAC_DIR}Xamarin.Forms/4.4.0.991864/ -name *.dll"):
+ return f"FAIL : The Xamarin.Forms/4.4.0.991864 nuget should not exist in {RO_TAC_DIR}"
+
+ return "PASS"
+
+# The `Launcher_TC_TAC_08` application should be applied to TAC, but The `Launcher_TC_TAC_09` application should not be applied to TAC.
+def TC_07():
+ raw = cmd(f"shell find {FRAMEWORK_DIR}/XSF.*")
+ if "XSF.dll" in raw:
+ cmd(f"shell mv {FRAMEWORK_DIR}/XSF.dll {FRAMEWORK_DIR}/XSF.dll2")
+ elif "XSF.ni.dll" in raw:
+ cmd(f"shell mv {FRAMEWORK_DIR}/XSF.ni.dll {FRAMEWORK_DIR}/XSF.ni.dll2")
+
+ sln_name = "Launcher_TC_TAC_08.Tizen"
+
+ tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
+ if tpk_path == None:
+ return f"FAIL : Get the tpk path for {sln_name}"
+
+ raw = cmd(f"push {tpk_path} /usr/apps/.preload-tpk/")
+ if "1 file(s) pushed. 0 file(s) skipped." in raw:
+ cmd(f"shell install_preload_pkg")
+
+ pkg_id = f"org.tizen.example.Launcher_TC_TAC_08.Tizen"
+
+ root_path = get_root_path(f"{pkg_id}")
+ if root_path == "None":
+ return f"FAIL : Get the root path for {pkg_id}"
+
+ if not exist(f"{root_path}/bin/.tac_symlink"):
+ return "FAIL : The .tac_symlink folder should exist"
+
+ raw = cmd(f"shell find {root_path}/bin/.tac_symlink/ -name *.dll -not -name *.ni.dll")
+ lines1 = [l for l in raw.splitlines()]
+ raw = cmd(f"shell find {RO_TAC_DIR}XSF/1.0.0.0/ -name *.dll -not -name *.ni.dll")
+ lines2 = [l for l in raw.splitlines()]
+ if len(lines1) != len(lines2):
+ return "FAIL : The number of .dll in the .tac_symlink and .dll in the TAC must match"
+
+ raw = cmd(f"shell ls -alZ {root_path}/bin/.tac_symlink/*.dll")
+ lines = [l for l in raw.splitlines() if ".ni.dll" not in l]
+ for dll in lines:
+ origin_path = dll.split("->")[1].strip()
+ if not exist(f"{origin_path}"):
+ return "FAIL : The original file of the symbolic link must exist"
+
+ sln_name = "Launcher_TC_TAC_09.Tizen"
+
+ tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
+ if tpk_path == None:
+ return f"FAIL : Get the tpk path for {sln_name}"
+
+ raw = cmd(f"push {tpk_path} /usr/apps/.preload-tpk/")
+ if "1 file(s) pushed. 0 file(s) skipped." in raw:
+ cmd(f"shell install_preload_pkg")
+
+ pkg_id = f"org.tizen.example.Launcher_TC_TAC_09.Tizen"
+
+ root_path = get_root_path(f"{pkg_id}")
+ if root_path == "None":
+ return f"FAIL : Get the root path for {pkg_id}"
+
+ raw = cmd(f"shell find {root_path}/bin/.tac_symlink -name XSF.dll -not -name XSF.ni.dll")
+ lines = [l for l in raw.splitlines()]
+ if len(lines) != 0:
+ return "FAIL : The version is the same Nuget, but the SHA value is different"
+
+ pid = launch_and_get_pid(f"-e", f"{pkg_id}")
+ if 0 == pid:
+ return f"FAIL : Get the pid for {pkg_id}"
+
+ raw = cmd(f"shell cat /proc/{pid}/smaps | grep XSF.dll")
+ if f"{root_path}/bin/XSF.dll" not in raw:
+ return "FAIL : The XSF in the application should be loaded when running the application"
+
+ cmd(f"shell app_launcher -t {pkg_id}")
+
+ return "PASS"
+
+# The Launcher_TC_TAC_10 application should match the information of nuget with the value of TAC DB.
+def TC_08():
+ sln_name = "Launcher_TC_TAC_10.Tizen"
+
+ tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
+ if tpk_path == None:
+ return f"FAIL : Get the tpk path for {sln_name}"
+
+ raw = cmd(f"push {tpk_path} /usr/apps/.preload-tpk/")
+ if "1 file(s) pushed. 0 file(s) skipped." in raw:
+ cmd(f"shell install_preload_pkg")
+
+ pkg_id = f"org.tizen.example.Launcher_TC_TAC_10.Tizen"
+
+ root_path = get_root_path(f"{pkg_id}")
+ if root_path == "None":
+ return f"FAIL : Get the root path for {pkg_id}"
+
+ if not exist(f"{root_path}/bin/.tac_symlink"):
+ return "FAIL : The .tac_symlink folder should exist"
+
+ raw = subprocess.run((f"sdb -s {serial} shell sqlite3 {RO_TAC_DIR}.TAC.App.list.db").split(), stdout=subprocess.PIPE, input=f"select * from TAC;\n.q\n", encoding="utf-8").stdout
+ lines = [l for l in raw.splitlines() if f"{pkg_id}" in l]
+ for rcd in lines:
+ is_exist = False
+ if ("Xamarin.Forms/4.8.0.1560" in rcd) or \
+ ("Newtonsoft.Json/12.0.3" in rcd) or \
+ ("Google.Apis.Core/1.49.0" in rcd) or \
+ ("Google.Apis/1.49.0" in rcd):
+ is_exist = True
+ continue
+ if not is_exist:
+ return "FAIL : TAC database must have a valid value"
+
+ return "PASS"
+
+# The Launcher_TC_TAC_11 application must match the version of the nuget in .deps.json and the version of the nuget in TAC DB.
+def TC_09():
+ sln_name = "Launcher_TC_TAC_11.Tizen"
+
+ tpk_path = get_tpk_path(tpk_list, f"{sln_name}")
+ if tpk_path == None:
+ return f"FAIL : Get the tpk path for {sln_name}"
+
+ raw = cmd(f"push {tpk_path} /usr/apps/.preload-tpk/")
+ if "1 file(s) pushed. 0 file(s) skipped." in raw:
+ cmd(f"shell install_preload_pkg")
+
+ pkg_id = f"org.tizen.example.Launcher_TC_TAC_11.Tizen"
+
+ root_path = get_root_path(f"{pkg_id}")
+ if root_path == "None":
+ return f"FAIL : Get the root path for {pkg_id}"
+
+ raw = subprocess.run((f"sdb -s {serial} shell sqlite3 {RO_TAC_DIR}.TAC.App.list.db").split(), stdout=subprocess.PIPE, input=f"select * from TAC;\n.q\n", encoding="utf-8").stdout
+ lines = [l for l in raw.splitlines() if f"{pkg_id}" in l]
+ for nuget in lines:
+ name = nuget.split("|")[3]
+ version = nuget.split("|")[4]
+ raw = cmd(f"shell cat {root_path}/{sln_name}.deps.json | grep {name}/")
+ if f"{version}" not in f"{raw}":
+ return "FAIL : "
+
+ return "PASS"
+
+# Run the test
+def run():
+ cmd(f"root on")
+ cmd(f"shell mount -o remount,rw /")
+
+ global tpk_list
+ tpk_list = search_tpk(f"{module_name}")
+
+ pn = run_tc_array(module_name, tc_array)
+ n = int(pn.split(":")[0])
+ f = int(pn.split(":")[1])
+ p = int(pn.split(":")[2])
+ r = 0.0
+ if (len(tc_array) - n) != 0:
+ r = round(((p / (len(tc_array) - n)) * 100), 2)
+ print(f"--- {module_name}_RO TCT Result ---\nNONE : [{n}] / FAIL : [{f}] / PASS : [{p}] - [{r}%]\n")
+
+ with open(f"{RESULT_PATH}", "a+") as file:
+ file.write(f"| {module_name}_RO | {p} | {f} | {n} | {r} |\n")
+
+# Uninstall the application and restore to original state
+def clean():
+ cmd(f"shell tpk-backend --force-remove --preload -d org.tizen.example.Launcher_TC_TAC_00.Tizen")
+ cmd(f"shell tpk-backend --force-remove --preload -d org.tizen.example.Launcher_TC_TAC_01.Tizen")
+ cmd(f"shell tpk-backend --force-remove --preload -d org.tizen.example.Launcher_TC_TAC_06.Tizen")
+ cmd(f"shell tpk-backend --force-remove --preload -d org.tizen.example.Launcher_TC_TAC_07.Tizen")
+ cmd(f"shell tpk-backend --force-remove --preload -d org.tizen.example.Launcher_TC_TAC_08.Tizen")
+ cmd(f"shell tpk-backend --force-remove --preload -d org.tizen.example.Launcher_TC_TAC_09.Tizen")
+ cmd(f"shell tpk-backend --force-remove --preload -d org.tizen.example.Launcher_TC_TAC_10.Tizen")
+ cmd(f"shell tpk-backend --force-remove --preload -d org.tizen.example.Launcher_TC_TAC_11.Tizen")
+
+ cmd(f"shell mv {FRAMEWORK_DIR}/XSF.dll2 {FRAMEWORK_DIR}/XSF.dll")
+ cmd(f"shell mv {FRAMEWORK_DIR}/XSF.ni.dll2 {FRAMEWORK_DIR}/XSF.ni.dll")
+
+# Main entry point
+def main():
+ parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter)
+ parser.add_argument("TC_NUMBER", type=str, nargs="*", help="Individual excution")
+ args = parser.parse_args()
+
+ global tc_array
+ if args.TC_NUMBER and "TC_" in args.TC_NUMBER[0]:
+ tc_array = []
+ for tc_num in args.TC_NUMBER:
+ if tc_num not in funcMap:
+ print(f"There is no {tc_num} test.")
+ exit(1)
+ else:
+ tc_array.append(funcMap[tc_num])
+ else:
+ tc_array = [TC_01, TC_02, TC_03, TC_04, TC_05, TC_06, TC_07, TC_08, TC_09]
+
+ global serial
+ if len(sys.argv) >= 2 and "TC_" not in sys.argv[1]:
+ serial = read_serial(sys.argv[1])
+ else:
+ serial = read_serial(None)
+
+ if serial is None:
+ print("No connected device(s).")
+ exit(1)
+
+ device = get_device_type()
+ print(f"=== Dotnet-Launcher [{device}] Test Case - ({module_name}_RO) ===")
+
+ run()
+ clean()
+
+
+funcMap = {
+'TC_01': TC_01, 'TC_02': TC_02, 'TC_03': TC_03, 'TC_04': TC_04, 'TC_05': TC_05, 'TC_06': TC_06, 'TC_07': TC_07, 'TC_08': TC_08, 'TC_09': TC_09,
+'TAC_TC_01': TC_01, 'TAC_TC_02': TC_02, 'TAC_TC_03': TC_03, 'TAC_TC_04': TC_04, 'TAC_TC_05': TC_05,
+'TAC_TC_06': TC_06, 'TAC_TC_07': TC_07, 'TAC_TC_08': TC_08, 'TAC_TC_09': TC_09
+}
+
+
+if __name__ == "__main__":
+ try:
+ main()
+ except KeyboardInterrupt:
+ print("\nExit (Pressed Ctrl+C)")
+ exit(1)
r = 0.0
if (len(tc_array) - n) != 0:
r = round(((p / (len(tc_array) - n)) * 100), 2)
- print(f"--- {module_name} TCT Result ---\nNONE : [{n}] / FAIL : [{f}] / PASS : [{p}] - [{r}%]\n")
+ print(f"--- {module_name}_RW TCT Result ---\nNONE : [{n}] / FAIL : [{f}] / PASS : [{p}] - [{r}%]\n")
with open(f"{RESULT_PATH}", "a+") as file:
- file.write(f"| {module_name} | {p} | {f} | {n} | {r} |\n")
+ file.write(f"| {module_name}_RW | {p} | {f} | {n} | {r} |\n")
# Uninstall the application and restore to original state
def clean():
exit(1)
device = get_device_type()
- print(f"=== Dotnet-Launcher [{device}] Test Case - ({module_name}) ===")
+ print(f"=== Dotnet-Launcher [{device}] Test Case - ({module_name}_RW) ===")
run()
clean()
FRAMEWORK_DIR = "/usr/share/dotnet.tizen/framework/"
PRELOAD_DIR = "/usr/share/dotnet.tizen/preload/"
IBCDATA_DIR = "/usr/share/dotnet.tizen/ibcdata/"
+RO_TAC_DIR = "/usr/share/dotnet.tizen/tac/"
DOTNET_DIR = "/opt/usr/dotnet/"
OWNER_DIR = "/home/owner/"
SPC_DLL = "System.Private.CoreLib.dll"