1 // Copyright 2019 Samsung Electronics. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
9 #include <privileged-service/PS_API.h>
13 #include <sys/types.h>
15 #include <vconf/vconf.h>
16 #include <vconf/vconf_rtc.h>
20 #include "chromium_impl/build/tizen_version.h"
23 #include "dlog_util.h"
25 // Check if path is real path(not symbolic link) or does not exist.
26 static bool is_real_path(const char* path) {
28 if (lstat(path, &ls) == -1) {
32 LOG(ERROR) << "Failed lstat(" << path << ") : " << errno;
35 if (!S_ISLNK(ls.st_mode))
37 LOG(ERROR) << path << " is symbolic link.";
43 std::ofstream TizenDlogWrapper::fstream_ = []() {
44 const char* file_log_path = "/tmp/chromium-efl-install.log";
45 return is_real_path(file_log_path)
46 ? std::ofstream(file_log_path, std::ios::out | std::ios::app)
49 __attribute__((destructor)) void close_log_file() {
50 TizenDlogWrapper::fstream_.close();
54 #define PATH_PRELOAD_CHROMIUM_EFL_IMG APP_RO_ROOT_DIR "/res/chromium-efl.img"
55 #define PATH_UPDATED_CHROMIUM_EFL_IMG APP_RW_ROOT_DIR "/res/chromium-efl.img"
57 // tv has 3-package 2-lib policy. Upgraded engine is used optionally.
58 // 1) preload package /ro/... -> /usr/share/.../lib
59 // 2) updated package /rw/... -> /usr/share/.../lib
60 // 3) upgrade package /rw/...-upgrade -> /usr/share/.../lib/upgrade
61 #define PATH_UPGRADE_CHROMIUM_EFL_IMG \
62 APP_UPGRADE_ROOT_DIR "/res/chromium-efl.img"
64 #define MOUNT_ARGS_PRELOAD_CHROMIUM \
65 PATH_PRELOAD_CHROMIUM_EFL_IMG " " LIB_RO_ROOT_DIR " -t squashfs -o loop,ro"
66 #define MOUNT_ARGS_UPDATED_CHROMIUM \
67 PATH_UPDATED_CHROMIUM_EFL_IMG " " LIB_RO_ROOT_DIR " -t squashfs -o loop,ro"
68 #define MOUNT_ARGS_UPGRADE_CHROMIUM \
69 PATH_UPGRADE_CHROMIUM_EFL_IMG " " LIB_UPGRADE_ROOT_DIR \
70 " -t squashfs -o loop,ro"
72 #define UMOUNT_ARGS_PREFIX "-dl "
76 const char* kChromiumMountReady = "/tmp/.chromium_mount.ready";
77 const char* kColdBootRequester = "chromium-efl";
78 const char* kLaunchFail = "rtc/memory/WebApp/LaunchFail";
79 const char* kPSAgentReady = "/run/ps_agent.pid";
80 const char* kSetColdBoot = "memory/boot/cold_poweroff_request_pkg";
81 std::string kTargetTPK;
82 const unsigned int kPSAgentTimeout = 30000;
84 static bool ps_agent_ready = false;
85 static bool WaitPSAgentReady() {
90 LOG(INFO) << "Waiting the ps_agent ready";
91 while (maxRetry != 0) {
92 int ret = LwipcWaitEvent(kPSAgentReady, kPSAgentTimeout);
94 LOG(INFO) << "ps_agent is ready";
95 ps_agent_ready = true;
100 LOG(ERROR) << "ps_agent is not ready : " << (ret > 0 ? "timeout" : "fail")
101 << ", remain retry [" << maxRetry << "]";
107 static void SetErrMsg(const std::string& mount_error) {
108 std::string vconfValue = kTargetTPK + mount_error;
109 LOG(ERROR) << "vconf : " << kLaunchFail << " value : " << vconfValue;
110 vconf_set_str_rtc(kLaunchFail, vconfValue.c_str());
113 static void RequestColdBoot() {
114 LOG(INFO) << "Request Cold Boot";
115 if (vconf_set_str(kSetColdBoot, kColdBootRequester) != 0)
116 LOG(ERROR) << "Request Cold Boot Fail";
119 // tv has different mount method and no tpk self-installation
120 static int mount(bool mount, const char* args, bool use_system = false) {
121 #define DEBUG_LOG_SMACK_LABEL 0
122 #if DEBUG_LOG_SMACK_LABEL
123 FILE* fd = fopen("/proc/self/attr/current", "r");
126 if (fgets(line, sizeof(line), fd))
127 LOG(INFO) << "SMACK Label:" << line;
132 if (WaitPSAgentReady() == false)
133 LOG(ERROR) << "Chromium-efl mount may not work.";
135 LOG(INFO) << "mount:" << mount << ", args: \"" << args << "\"";
137 int result = SUCCESS;
140 #if TIZEN_VERSION_AT_LEAST(7, 0, 0)
141 rv = PS_Mount_Fast(args, strlen(args) + 1, 1, &result);
143 rv = PS_Mount(args, strlen(args) + 1, 1, &result);
147 rv = PS_Umount(args, strlen(args) + 1, 1, &result);
148 LOG(INFO) << "result = " << rv << ", " << result;
149 if (rv != SUCCESS || result != SUCCESS) {
150 std::string mount_error = "mount failed. (" + std::to_string(rv) + ", " +
151 std::to_string(result) + ")";
152 SetErrMsg(mount_error);
156 if (LwipcEventDone(kChromiumMountReady) < 0) {
157 // The Lwipc api simply calls the ioctl() inside the function.
158 // Failure of this API means that there are some kernel issues.
159 LOG(ERROR) << kChromiumMountReady << " Event Failed.";
165 static int MountPatchedTPK() {
167 if (!access(LIB_RO_ROOT_DIR "/version", F_OK)) {
168 LOG(INFO) << LIB_RO_ROOT_DIR "/version file already exists.";
169 if (LwipcEventDone(kChromiumMountReady) < 0) {
170 // The Lwipc api simply calls the ioctl() inside the function.
171 // Failure of this API means that there are some kernel issues.
172 LOG(ERROR) << kChromiumMountReady << " Event Failed.";
177 if (!access(PATH_UPDATED_CHROMIUM_EFL_IMG, F_OK)) {
178 LOG(INFO) << PATH_UPDATED_CHROMIUM_EFL_IMG << " exists.";
179 kTargetTPK = "WebEngine Updated TPK ";
180 result = mount(true, MOUNT_ARGS_UPDATED_CHROMIUM);
183 if (result != SUCCESS && !access(PATH_PRELOAD_CHROMIUM_EFL_IMG, F_OK)) {
184 LOG(INFO) << PATH_PRELOAD_CHROMIUM_EFL_IMG << " exists.";
185 kTargetTPK = "WebEngine Preload TPK ";
186 result = mount(true, MOUNT_ARGS_PRELOAD_CHROMIUM);
192 static void MountUpgradeTPK() {
193 if (!access(LIB_UPGRADE_ROOT_DIR "/version", F_OK)) {
195 LOG(INFO) << LIB_UPGRADE_ROOT_DIR "/version file already exists.";
198 if (!access(PATH_UPGRADE_CHROMIUM_EFL_IMG, F_OK)) {
199 LOG(INFO) << PATH_UPGRADE_CHROMIUM_EFL_IMG << " exists.";
200 kTargetTPK = "WebEngine Upgrade TPK ";
201 mount(true, MOUNT_ARGS_UPGRADE_CHROMIUM);
203 LOG(INFO) << "No WebEngine Upgrade TPK found";
214 int main(int argc, char* argv[]) {
215 LOG(INFO) << argv[0] << " started.";
217 bool is_remove_tpk = false;
219 Options option = InstallTpk;
221 for (int i = 1; i < argc; i++) {
222 if (!strcmp(argv[i], "--mount")) {
224 } else if (!strcmp(argv[i], "--umount")) {
226 } else if (!strcmp(argv[i], "--umount-all")) {
228 } else if (option == InstallTpk) {
229 if (!strcmp(argv[i], "-d")) {
230 is_remove_tpk = true;
232 args.append(argv[i]);
234 } else if (option == Mount || option == Umount) {
235 if (args.length() > 0)
237 args.append(argv[i]);
239 LOG(WARN) << "Unknown Argument : " << argv[i];
243 if (option == InstallTpk) { // InstallTpk
244 // TV does not install tpk. Built-in installer installs.
245 // To avoid concurrency problem, a lock must be shared with installer.
247 // Mount patched/preload chromium-efl.img (Mandatory)
248 result = MountPatchedTPK();
249 if (result != SUCCESS)
252 // Mount upgrade chromium-efl.img (Optional)
255 LOG(WARN) << "'-d' option is not supported for tv";
258 if (option == Mount || option == Umount) {
259 result = mount(option == Mount, args.c_str());
260 } else if (option == UmountAll) {
261 if (!access(LIB_UPGRADE_ROOT_DIR "/version", F_OK)) {
262 mount(false, UMOUNT_ARGS_PREFIX LIB_UPGRADE_ROOT_DIR);
264 if (!access(LIB_RO_ROOT_DIR "/version", F_OK)) {
265 mount(false, UMOUNT_ARGS_PREFIX LIB_RO_ROOT_DIR);
270 LOG(INFO) << argv[0] << " ended. result:" << result;