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