Add a plugin for app-defined loader
[platform/core/appfw/launchpad.git] / parser / launchpad_parser_plugin.cc
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <fstream>
18 #include <string>
19
20 #include <sys/stat.h>
21 #include <unistd.h>
22
23 #include "launchpad_parser_plugin.hh"
24 #include "log_private.hh"
25
26 #define LOADERS_DIRECTORY_PATH "/opt/share/loaders/"
27
28 using namespace std;
29 namespace launchpad_parser_plugin {
30
31 string LaunchpadParser::GetFilePath(string id) {
32   return "/opt/share/loaders/" + id + ".loader";
33 }
34
35 int LaunchpadParser::WriteToFile(string pkgid) {
36   if (access(LOADERS_DIRECTORY_PATH, F_OK) != 0)
37     mkdir(LOADERS_DIRECTORY_PATH, 0644);
38
39   LOGI("write to file (%d)", loader_list_.size());
40   for (auto& i : loader_list_) {
41     std::ofstream out_file;
42     LOGI("write ID (%s)", i->GetId().c_str());
43     out_file.open(GetFilePath(i->GetId()));
44     out_file << "[LOADER]\n";
45     out_file << "NAME " + i->GetId() + "\n";
46     out_file << "EXE  /usr/bin/launchpad-loader \n";
47     out_file << "APP_TYPE  capp|c++app \n";
48     out_file << "DETECTION_METHOD  TIMEOUT|VISIBILITY \n";
49     out_file << "TIMEOUT    5000 \n";
50     out_file << "TTL    " + to_string(i->GetTimeToLive()) + "\n";
51     out_file << "OWNER    " + pkgid + "\n";
52     out_file << "EXTRA    loader_type  common-loader \n";
53     if (i->GetPreloadLib().size() > 0) {
54       out_file << "EXTRA_ARRAY    preload \n";
55       for (auto& lib : i->GetPreloadLib()) {
56         out_file << "EXTRA_ARRAY_VAL    /usr/lib/" + lib + "\n";
57       }
58     }
59     out_file.close();
60   }
61   return 0;
62 }
63
64 bool LaunchpadParser::IsValidId(string loader_id, string pkgid) {
65   ifstream in_file(GetFilePath(loader_id).c_str());
66   if (!in_file.good())
67     return true;
68   string key, val;
69   in_file >> key;
70   while (in_file >> key >> val) {
71     if (key == "OWNER") {
72       LOGI("key (%s), val (%s)", key.c_str(), val.c_str());
73       if (val == pkgid)
74         return true;
75     }
76   }
77   return false;
78 }
79
80 int LaunchpadParser::Install(xmlDocPtr doc, string pkgid) {
81   xmlNode* root = xmlDocGetRootElement(doc);
82   for (xmlNode* node = root->children; node; node = node->next) {
83     if (!node->name)
84       continue;
85
86     string name = string((char*)node->name);
87     if (name != "provides-appdefined-loader")
88       continue;
89
90     xmlChar* val = xmlGetProp(node, (const xmlChar *)"id");
91     shared_ptr<LoaderInfo> info = make_shared<LoaderInfo>(string((char*)val));
92     if (!IsValidId(info->GetId(), pkgid))
93       return -1;
94
95     xmlChar* ttl = xmlGetProp(node, (const xmlChar *)"time-to-live");
96     if (ttl)
97       info->SetTimeToLive(stoi(string((char*)ttl)));
98
99     for (xmlNode* iter = node->children; iter; iter = iter->next) {
100       if (!iter->name)
101         continue;
102       string child_name = string((char*)iter->name);
103       if (child_name == "preload-library") {
104         xmlChar* libname = xmlGetProp(iter, (const xmlChar *)"name");
105         if (!libname)
106           continue;
107         info->AddPreloadLib(string((char*)libname));
108       }
109     }
110     loader_list_.push_back(info);
111   }
112   WriteToFile(pkgid);
113
114   return 0;
115 }
116
117 int LaunchpadParser::Upgrade(xmlDocPtr doc, std::string pkgid) {
118   if (UnInstall(doc, pkgid) != 0)
119     return -1;
120
121   return Install(doc, pkgid);
122 }
123
124 int LaunchpadParser::UnInstall(xmlDocPtr doc, std::string pkgid) {
125   xmlNode* root = xmlDocGetRootElement(doc);
126   for (xmlNode* node = root->children; node; node = node->next) {
127     if (!node->name)
128       continue;
129
130     string name = string((char*)node->name);
131     if (name != "provides-appdefined-loader")
132       continue;
133
134     xmlChar* val = xmlGetProp(node, (const xmlChar *)"id");
135     if (!val)
136       return -1;
137
138     string id = string((char*)val);
139     if (!IsValidId(id, pkgid))
140         return -1;
141     remove(GetFilePath(id).c_str());
142   }
143   return 0;
144 }
145
146 }   // namspace launchpad_parser_plugin