Upstream version 10.39.225.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   if (!base::PathExists(base::FilePath(pkg_path))) {
85     return kPkgmgrPluginFalse;
86   }
87
88   base::ScopedTempDir dir;
89   dir.CreateUniqueTempDir();
90   scoped_refptr<xwalk::application::ApplicationData> app_data =
91       GetApplicationDataFromPkg(pkg_path, &dir);
92   if (app_data.get() == NULL) {
93     return kPkgmgrPluginFalse;
94   }
95
96   SaveDetailInfo(app_data, pkg_detail_info);
97   return kPkgmgrPluginTrue;
98 }
99
100 int PkgmgrBackendPlugin::IsAppInstalled(const std::string& pkgid) {
101   // this will fetch app_id if exists
102   std::string app_id = xwalk::application::PkgIdToAppId(pkgid);
103   return app_id.empty() ? kPkgmgrPluginFalse : kPkgmgrPluginTrue;
104 }
105
106 int PkgmgrBackendPlugin::AppsList(package_manager_pkg_info_t** list,
107                                   int* count) {
108   *list = NULL;
109   *count = 0;
110   std::vector<std::string> app_ids;
111   if (!storage_->GetInstalledApplicationIDs(app_ids)) {
112     return kPkgmgrPluginFalse;
113   }
114   for (std::vector<std::string>::const_iterator citer = app_ids.begin();
115        citer != app_ids.end(); ++citer) {
116     scoped_refptr<xwalk::application::ApplicationData> app_data =
117         storage_->GetApplicationData(*citer);
118     if (app_data.get() != NULL) {
119       package_manager_pkg_info_t* result =
120           static_cast<package_manager_pkg_info_t*>(
121               malloc(sizeof(package_manager_pkg_info_t)));
122       memset(result, 0x00, sizeof(package_manager_pkg_info_t));
123       SaveInfo(app_data, result);
124       if (*list) {
125         result->next = *list;
126       }
127       *list = result;
128       ++*count;
129     }
130   }
131   return kPkgmgrPluginTrue;
132 }
133
134 PkgmgrBackendPlugin::PkgmgrBackendPlugin() {
135   base::FilePath data_path;
136   xwalk::RegisterPathProvider();
137   PathService::Get(xwalk::DIR_DATA_PATH, &data_path);
138   storage_.reset(new xwalk::application::ApplicationStorage(data_path));
139 }
140
141 void PkgmgrBackendPlugin::SaveInfo(
142     scoped_refptr<xwalk::application::ApplicationData> app_data,
143     package_manager_pkg_info_t* pkg_detail_info) {
144   strncpy(pkg_detail_info->pkg_type, "xpk", PKG_TYPE_STRING_LEN_MAX - 1);
145   strncpy(pkg_detail_info->pkg_name, app_data->GetPackageID().c_str(),
146           PKG_NAME_STRING_LEN_MAX - 1);
147   strncpy(pkg_detail_info->pkgid, app_data->GetPackageID().c_str(),
148           PKG_NAME_STRING_LEN_MAX - 1);
149   if (app_data->Version() != NULL) {
150     strncpy(pkg_detail_info->version, app_data->Version()->GetString().c_str(),
151             PKG_VERSION_STRING_LEN_MAX - 1);
152   }
153 }
154
155 void PkgmgrBackendPlugin::SaveDetailInfo(
156     scoped_refptr<xwalk::application::ApplicationData> app_data,
157     package_manager_pkg_detail_info_t* pkg_detail_info) {
158   strncpy(pkg_detail_info->pkg_type, "xpk", PKG_TYPE_STRING_LEN_MAX - 1);
159   strncpy(pkg_detail_info->pkg_name, app_data->GetPackageID().c_str(),
160           PKG_NAME_STRING_LEN_MAX - 1);
161   strncpy(pkg_detail_info->pkgid, app_data->GetPackageID().c_str(),
162           PKG_NAME_STRING_LEN_MAX - 1);
163   if (app_data->Version() != NULL) {
164     strncpy(pkg_detail_info->version, app_data->Version()->GetString().c_str(),
165             PKG_VERSION_STRING_LEN_MAX - 1);
166   }
167   strncpy(pkg_detail_info->pkg_description, app_data->Description().c_str(),
168           PKG_VALUE_STRING_LEN_MAX - 1);
169
170   // xpk do not have this key in manifest
171   if (app_data->manifest_type() == Manifest::TYPE_WIDGET) {
172     const xwalk::application::TizenApplicationInfo* tizen_app_info =
173         static_cast<xwalk::application::TizenApplicationInfo*>(
174             app_data->GetManifestData(
175                 xwalk::application_widget_keys::kTizenApplicationKey));
176     DCHECK(tizen_app_info);
177
178     strncpy(pkg_detail_info->min_platform_version,
179         tizen_app_info->required_version().c_str(),
180         PKG_VERSION_STRING_LEN_MAX -1);
181   }
182
183   pkg_detail_info->installed_time =
184       xwalk::application::GetApplicationInstallationTime(app_data->ID())
185           .ToTimeT();  // to seconds
186
187   int install_size = CountAppTotalSize(app_data);
188   int data_size = CountAppDataSize(app_data);
189   pkg_detail_info->installed_size = install_size;
190   pkg_detail_info->app_size = install_size - data_size;
191   pkg_detail_info->data_size = data_size;
192
193   strncpy(pkg_detail_info->optional_id, app_data->GetPackageID().c_str(),
194           PKG_NAME_STRING_LEN_MAX - 1);
195   pkg_detail_info->pkg_optional_info = NULL;
196 }
197
198 scoped_refptr<xwalk::application::ApplicationData>
199 PkgmgrBackendPlugin::GetApplicationDataFromPkg(const std::string& pkg_path,
200     base::ScopedTempDir* dir) {
201   base::FilePath unpacked_dir = dir->path();
202
203   scoped_ptr<xwalk::application::Package> package =
204       xwalk::application::Package::Create(base::FilePath(pkg_path));
205   if (!package)
206     return nullptr;
207   package->ExtractToTemporaryDir(&unpacked_dir);
208   std::string app_id = package->Id();
209
210   std::string error;
211   scoped_refptr<xwalk::application::ApplicationData> app_data = LoadApplication(
212       unpacked_dir, app_id, xwalk::application::ApplicationData::TEMP_DIRECTORY,
213       package->manifest_type(), &error);
214   return app_data;
215 }