Upstream version 11.39.244.0
[platform/framework/web/crosswalk.git] / src / xwalk / application / tools / tizen / xwalk_backend_plugin.cc
1 // Copyright (c) 2014 Samsung Electronics Co., Ltd 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.
4
5 #include "xwalk/application/tools/tizen/xwalk_backend_plugin.h"
6
7 #include <cstdlib>
8 #include <cstring>
9 #include <vector>
10
11 #include "base/file_util.h"
12 #include "base/files/file_path.h"
13 #include "base/files/scoped_temp_dir.h"
14 #include "base/logging.h"
15 #include "base/path_service.h"
16 #include "base/time/time.h"
17 #include "base/version.h"
18 #include "xwalk/application/common/application_data.h"
19 #include "xwalk/application/common/application_file_util.h"
20 #include "xwalk/application/common/application_manifest_constants.h"
21 #include "xwalk/application/common/id_util.h"
22 #include "xwalk/application/common/manifest_handlers/tizen_application_handler.h"
23 #include "xwalk/application/common/package/package.h"
24 #include "xwalk/application/common/tizen/package_query.h"
25 #include "xwalk/runtime/common/xwalk_paths.h"
26
27 using xwalk::application::Manifest;
28
29 namespace {
30
31 enum PkgmgrPluginBool {
32   kPkgmgrPluginTrue = 0,
33   kPkgmgrPluginFalse = -1
34 };
35
36 // Whole app directory size in KB
37 int64 CountAppTotalSize(
38     scoped_refptr<xwalk::application::ApplicationData> app_data) {
39   return base::ComputeDirectorySize(app_data->path()) / 1024;
40 }
41
42 // Data directory size in KB
43 int64 CountAppDataSize(
44     scoped_refptr<xwalk::application::ApplicationData> app_data) {
45   int64 size = 0;
46
47   base::FilePath private_path = app_data->path().Append("private");
48   size += base::ComputeDirectorySize(private_path);
49
50   base::FilePath tmp_path = app_data->path().Append("tmp");
51   size += base::ComputeDirectorySize(tmp_path);
52
53   return size / 1024;
54 }
55
56 }  // namespace
57
58 PkgmgrBackendPlugin* PkgmgrBackendPlugin::GetInstance() {
59   return Singleton<PkgmgrBackendPlugin,
60                    PkgmgrBackendPluginTraits<PkgmgrBackendPlugin> >::get();
61 }
62
63 int PkgmgrBackendPlugin::DetailedInfo(
64     const std::string& pkgid,
65     package_manager_pkg_detail_info_t* pkg_detail_info) {
66
67   std::string app_id = xwalk::application::PkgIdToAppId(pkgid);
68
69   if (app_id.empty())
70     return kPkgmgrPluginFalse;
71
72   scoped_refptr<xwalk::application::ApplicationData> app_data =
73       storage_->GetApplicationData(app_id);
74   if (!app_data.get())
75     return kPkgmgrPluginFalse;
76
77   SaveDetailInfo(app_data, pkg_detail_info);
78   return kPkgmgrPluginTrue;
79 }
80
81 int PkgmgrBackendPlugin::DetailedInfoPkg(
82     const std::string& pkg_path,
83     package_manager_pkg_detail_info_t* pkg_detail_info) {
84   base::FilePath path(pkg_path);
85   if (!base::PathExists(path)) {
86     return kPkgmgrPluginFalse;
87   }
88
89   base::ScopedTempDir dir;
90   dir.CreateUniqueTempDir();
91   scoped_refptr<xwalk::application::ApplicationData> app_data =
92       GetApplicationDataFromPkg(pkg_path, &dir);
93   if (app_data.get() == NULL) {
94     return kPkgmgrPluginFalse;
95   }
96
97   SaveDetailInfo(app_data, pkg_detail_info,
98       !path.Extension().empty() ? path.Extension() : std::string("unknown"));
99   return kPkgmgrPluginTrue;
100 }
101
102 int PkgmgrBackendPlugin::IsAppInstalled(const std::string& pkgid) {
103   // this will fetch app_id if exists
104   std::string app_id = xwalk::application::PkgIdToAppId(pkgid);
105
106   if (app_id.empty())
107     return kPkgmgrPluginFalse;
108
109   // backendlib handles both xpk and wgt
110   // check if plugin was loaded for given type of package
111   std::string type_from_db = xwalk::application::GetPackageType(pkgid);
112
113   return type() == type_from_db ? kPkgmgrPluginTrue : kPkgmgrPluginFalse;
114 }
115
116 int PkgmgrBackendPlugin::AppsList(package_manager_pkg_info_t** list,
117                                   int* count) {
118   *list = NULL;
119   *count = 0;
120   std::vector<std::string> app_ids;
121   if (!storage_->GetInstalledApplicationIDs(app_ids)) {
122     return kPkgmgrPluginFalse;
123   }
124   for (std::vector<std::string>::const_iterator citer = app_ids.begin();
125        citer != app_ids.end(); ++citer) {
126     scoped_refptr<xwalk::application::ApplicationData> app_data =
127         storage_->GetApplicationData(*citer);
128     if (app_data.get() != NULL) {
129       package_manager_pkg_info_t* result =
130           static_cast<package_manager_pkg_info_t*>(
131               malloc(sizeof(package_manager_pkg_info_t)));
132       memset(result, 0x00, sizeof(package_manager_pkg_info_t));
133       SaveInfo(app_data, result);
134       if (*list) {
135         result->next = *list;
136       }
137       *list = result;
138       ++*count;
139     }
140   }
141   return kPkgmgrPluginTrue;
142 }
143
144 void PkgmgrBackendPlugin::SetLoadSet(pkg_plugin_set* set) {
145   set_ = set;
146 }
147
148 std::string PkgmgrBackendPlugin::type() const {
149   return std::string(set_->pkg_type);
150 }
151
152 PkgmgrBackendPlugin::PkgmgrBackendPlugin() {
153   base::FilePath data_path;
154   xwalk::RegisterPathProvider();
155   PathService::Get(xwalk::DIR_DATA_PATH, &data_path);
156   storage_.reset(new xwalk::application::ApplicationStorage(data_path));
157 }
158
159 void PkgmgrBackendPlugin::SaveInfo(
160     scoped_refptr<xwalk::application::ApplicationData> app_data,
161     package_manager_pkg_info_t* pkg_detail_info,
162     const std::string& force_type) {
163   std::string pkg_id = app_data->GetPackageID();
164   if (force_type.empty())
165     strncpy(pkg_detail_info->pkg_type,
166             xwalk::application::GetPackageType(pkg_id).c_str(),
167             PKG_TYPE_STRING_LEN_MAX - 1);
168   else  // force package type
169     strncpy(pkg_detail_info->pkg_type,
170             force_type.c_str(),
171             PKG_TYPE_STRING_LEN_MAX - 1);
172   strncpy(pkg_detail_info->pkg_name, pkg_id.c_str(),
173           PKG_NAME_STRING_LEN_MAX - 1);
174   strncpy(pkg_detail_info->pkgid, pkg_id.c_str(),
175           PKG_NAME_STRING_LEN_MAX - 1);
176   if (app_data->Version() != NULL) {
177     strncpy(pkg_detail_info->version, app_data->Version()->GetString().c_str(),
178             PKG_VERSION_STRING_LEN_MAX - 1);
179   }
180 }
181
182 void PkgmgrBackendPlugin::SaveDetailInfo(
183     scoped_refptr<xwalk::application::ApplicationData> app_data,
184     package_manager_pkg_detail_info_t* pkg_detail_info,
185     const std::string& force_type) {
186   std::string pkg_id = app_data->GetPackageID();
187   if (force_type.empty())
188     strncpy(pkg_detail_info->pkg_type,
189             xwalk::application::GetPackageType(pkg_id).c_str(),
190             PKG_TYPE_STRING_LEN_MAX - 1);
191   else  // force package type
192     strncpy(pkg_detail_info->pkg_type,
193             force_type.c_str(),
194             PKG_TYPE_STRING_LEN_MAX - 1);
195   strncpy(pkg_detail_info->pkg_name, pkg_id.c_str(),
196           PKG_NAME_STRING_LEN_MAX - 1);
197   strncpy(pkg_detail_info->pkgid, pkg_id.c_str(),
198           PKG_NAME_STRING_LEN_MAX - 1);
199   if (app_data->Version() != NULL) {
200     strncpy(pkg_detail_info->version, app_data->Version()->GetString().c_str(),
201             PKG_VERSION_STRING_LEN_MAX - 1);
202   }
203   strncpy(pkg_detail_info->pkg_description, app_data->Description().c_str(),
204           PKG_VALUE_STRING_LEN_MAX - 1);
205
206   // xpk do not have this key in manifest
207   if (app_data->manifest_type() == Manifest::TYPE_WIDGET) {
208     const xwalk::application::TizenApplicationInfo* tizen_app_info =
209         static_cast<xwalk::application::TizenApplicationInfo*>(
210             app_data->GetManifestData(
211                 xwalk::application_widget_keys::kTizenApplicationKey));
212     DCHECK(tizen_app_info);
213
214     strncpy(pkg_detail_info->min_platform_version,
215             tizen_app_info->required_version().c_str(),
216             PKG_VERSION_STRING_LEN_MAX -1);
217   }
218
219   pkg_detail_info->installed_time =
220       xwalk::application::GetApplicationInstallationTime(app_data->ID())
221           .ToTimeT();  // to seconds
222
223   int install_size = CountAppTotalSize(app_data);
224   int data_size = CountAppDataSize(app_data);
225   pkg_detail_info->installed_size = install_size;
226   pkg_detail_info->app_size = install_size - data_size;
227   pkg_detail_info->data_size = data_size;
228
229   strncpy(pkg_detail_info->optional_id, app_data->GetPackageID().c_str(),
230           PKG_NAME_STRING_LEN_MAX - 1);
231   pkg_detail_info->pkg_optional_info = NULL;
232 }
233
234 scoped_refptr<xwalk::application::ApplicationData>
235 PkgmgrBackendPlugin::GetApplicationDataFromPkg(const std::string& pkg_path,
236                                                base::ScopedTempDir* dir) {
237   base::FilePath unpacked_dir = dir->path();
238   scoped_ptr<xwalk::application::Package> package =
239       xwalk::application::Package::Create(base::FilePath(pkg_path));
240   if (!package)
241     return nullptr;
242
243   package->ExtractToTemporaryDir(&unpacked_dir);
244   std::string error;
245   std::string app_id = package->Id();
246   scoped_refptr<xwalk::application::ApplicationData> app_data = LoadApplication(
247       unpacked_dir, app_id, xwalk::application::ApplicationData::TEMP_DIRECTORY,
248       package->manifest_type(), &error);
249
250   return app_data;
251 }