2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
24 #include <bundle_cpp.h>
26 #include <pkgmgr-info.h>
28 #include <system_info.h>
29 #include <cion/common/data_payload.hh>
32 #include "cion_ondemand_server.h"
33 #include "cion_peer_info.h"
34 #include "cion_module.hh"
38 std::string GetAppVersion(const std::string& appid) {
40 char *pkg_version = NULL;
41 pkgmgrinfo_appinfo_h appinfo = NULL;
43 int retval = pkgmgrinfo_appinfo_get_usr_appinfo(appid.c_str(),
45 if (retval != PMINFO_R_OK)
48 retval = pkgmgrinfo_appinfo_get_pkgid(appinfo, &pkgid);
49 if (retval != PMINFO_R_OK) {
50 pkgmgrinfo_appinfo_destroy_appinfo(appinfo);
54 pkgmgrinfo_pkginfo_h pkginfo = NULL;
55 retval = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &pkginfo);
56 if (retval != PMINFO_R_OK) {
57 pkgmgrinfo_appinfo_destroy_appinfo(appinfo);
61 retval = pkgmgrinfo_pkginfo_get_version(pkginfo, &pkg_version);
62 if (retval != PMINFO_R_OK) {
63 pkgmgrinfo_appinfo_destroy_appinfo(appinfo);
64 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
68 std::string version(pkg_version);
69 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
70 pkgmgrinfo_appinfo_destroy_appinfo(appinfo);
75 std::string GetSystemInfoPlatformString(const char* key) {
77 int ret = system_info_get_platform_string(key, &val);
78 if (ret != SYSTEM_INFO_ERROR_NONE || !val)
81 std::string val_str = val;
87 std::string GetVconfString(const char* key) {
88 char* val = vconf_get_str(key);
92 std::string val_str = val;
98 std::string device_id = GetSystemInfoPlatformString("http://tizen.org/system/tizenid");
99 std::string device_name = GetVconfString(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
100 std::string device_platform = "Tizen";
101 std::string device_platform_version =
102 GetSystemInfoPlatformString("http://tizen.org/feature/platform.version");
103 std::string device_type = GetSystemInfoPlatformString("http://tizen.org/system/device_type");
107 CionOndemandServer::CionOndemandServer(std::string service_name,
108 std::string display_name, esd::api::IModule* module)
109 : cion::channel::ServerChannel(service_name, display_name), module_(module) {
110 LoadOndemandServiceList();
113 CionOndemandServer::CionOndemandServer(std::string service_name,
114 std::string display_name, cion::SecurityInfo security) :
115 cion::channel::ServerChannel(service_name, display_name,
116 std::move(security)) {
117 LoadOndemandServiceList();
120 void CionOndemandServer::OnConnectionResult(std::shared_ptr<cion::PeerInfo> info,
121 const cion::ConnectionResult& result) {
124 void CionOndemandServer::OnDisconnected(std::shared_ptr<cion::PeerInfo> peer) {
127 std::vector<char> CionOndemandServer::OnDataReceived(
128 const std::vector<char>& data, std::shared_ptr<cion::PeerInfo> peer) {
129 std::string return_data("returned");
131 std::vector<char> v(return_data.begin(), return_data.end());
135 void CionOndemandServer::OnPayloadReceived(std::shared_ptr<cion::IPayload> data,
136 std::shared_ptr<cion::PeerInfo> peer,
137 IPayloadReceiver::PayloadTransferStatus status) {
140 void CionOndemandServer::OnConnectionRequest(
141 std::shared_ptr<cion::PeerInfo> peer) {
144 void CionOndemandServer::OnOndemandListRequested(
145 std::shared_ptr<cion::IPayload> data,
146 std::shared_ptr<cion::PeerInfo> peer) {
147 std::vector<uint8_t> raw;
149 _D("[Request Ondemand List]");
151 if (data->GetType() == cion::IPayload::PayloadType::File)
154 std::shared_ptr<cion::DataPayload> data_payload =
155 std::dynamic_pointer_cast<cion::DataPayload>(data);
156 std::vector<char> requested_data = data_payload->GetData();
157 tizen_base::Parcel ondemand_parcel(requested_data.data(),
158 requested_data.size());
160 std::string list_header = ondemand_parcel.ReadString();
161 std::string list_service_name = ondemand_parcel.ReadString();
162 _D("Ondemand Service_name : %s", list_service_name.c_str());
163 if (list_header == std::string("OndemandList")) {
164 raw = GetOndemandList(list_service_name).ToRaw();
169 auto dpl = std::make_unique<cion::DataPayload>();
170 std::vector<char> listdata_vector(raw.begin(), raw.end());
171 dpl->SetData(listdata_vector);
173 SendPayloadAsync(dpl.get(), peer, [] (
174 std::shared_ptr<cion::PayloadAsyncResult> result) {
175 _I("result received !!! %s", result->GetPayloadID().c_str());
179 int CionOndemandServer::OnOndemandLaunchRequested(
180 std::shared_ptr<cion::IPayload> data,
181 std::shared_ptr<cion::PeerInfo> peer) {
182 //TODO check privilege app_id
183 std::string app_id = peer->GetAppID();
186 cion::IPayload::PayloadType type = data->GetType();
187 if (type == cion::IPayload::PayloadType::File)
190 std::shared_ptr<cion::DataPayload> data_payload =
191 std::dynamic_pointer_cast<cion::DataPayload>(data);
193 std::vector<char> getdata = data_payload->GetData();
194 std::string launch_requested(getdata.begin(), getdata.end());
196 ret = OndemandLaunchApp(launch_requested);
198 _E("Faled to __esd_cion_launch_ondemand : %d", ret);
204 int CionOndemandServer::OndemandLaunchApp(std::string appid) {
205 uid_t uid = getuid();
206 tizen_base::Bundle b;
210 for (std::shared_ptr<CionPeerInfo> cs : ondemand_peer_list_) {
211 if (cs->GetAppID() == appid) {
217 if (found == false) {
218 _E("%s is not found", appid.c_str());
222 _D("cion launch ondemand: app_id(%s)", appid.c_str());
224 if (!aul_app_is_running_for_uid(appid.c_str(), uid)) {
225 aul_svc_set_operation(b.GetHandle(), AUL_SVC_OPERATION_DEFAULT);
226 aul_svc_set_appid(b.GetHandle(), appid.c_str());
228 ret = aul_svc_run_service_async_for_uid(b.GetHandle(), 0, NULL, NULL, uid);
230 _E("Failed to launch app : %s", appid.c_str());
233 _D("already is running or launch failed");
239 void CionOndemandServer::LoadOndemandServiceList() {
240 auto* mod = static_cast<esd::module::CionModule*>(module_);
241 auto ret = mod->GetEnabledServiceList();
246 for (const auto& i : *ret) {
247 std::optional<std::string> uuid;
248 mod->GetUuidWithGenerate(i.GetAppId(), uuid);
250 _E("Get uuid for %s", i.GetAppId().c_str());
253 std::string app_version = GetAppVersion(i.GetAppId());
254 tizen_base::Parcel parcel;
255 parcel.WriteString(device_id);
256 parcel.WriteString(device_name);
257 parcel.WriteString(device_platform);
258 parcel.WriteString(device_platform_version);
259 parcel.WriteString(device_type);
260 parcel.WriteString(i.GetAppId());
261 parcel.WriteString(app_version);
262 parcel.WriteString(*uuid);
263 parcel.WriteString(i.GetDisplayName());
265 std::shared_ptr<CionPeerInfo> pi =
266 std::make_shared<CionPeerInfo>(i.GetServiceName(),
267 parcel.GetData(), parcel.GetDataSize());
268 ondemand_peer_list_.emplace_back(pi);
272 void CionOndemandServer::AddOndemandServiceList(std::string service_name,
273 std::string appid, std::string display_name) {
274 for (auto const& peer : ondemand_peer_list_) {
275 if (peer->GetServiceName() == service_name &&
276 peer->GetAppID() == appid) {
277 _W("%s is already exist", appid.c_str());
282 std::optional<std::string> uuid;
283 auto* mod = static_cast<esd::module::CionModule*>(module_);
284 mod->GetUuidWithGenerate(appid, uuid);
286 _E("Get uuid for %s", appid.c_str());
290 std::string app_version = GetAppVersion(appid);
292 tizen_base::Parcel parcel;
293 parcel.WriteString(device_id);
294 parcel.WriteString(device_name);
295 parcel.WriteString(device_platform);
296 parcel.WriteString(device_platform_version);
297 parcel.WriteString(device_type);
298 parcel.WriteString(appid);
299 parcel.WriteString(app_version);
300 parcel.WriteString(*uuid);
301 parcel.WriteString(display_name);
303 std::shared_ptr<CionPeerInfo> pi =
304 std::make_shared<CionPeerInfo>(service_name, parcel.GetData(),
305 parcel.GetDataSize());
306 ondemand_peer_list_.emplace_back(pi);
308 _D("[%s:%s] is added to list", appid.c_str(), service_name.c_str());
311 void CionOndemandServer::RemoveOndemandServiceList(std::string service_name,
313 for (auto peer = ondemand_peer_list_.begin();
314 peer != ondemand_peer_list_.end(); peer++) {
315 if (peer->get()->GetServiceName() == service_name &&
316 peer->get()->GetAppID() == appid) {
317 ondemand_peer_list_.erase(peer);
318 _D("[%s:%s] is removed from list", appid.c_str(), service_name.c_str());
324 tizen_base::Parcel CionOndemandServer::GetOndemandList(
325 std::string service_name) {
326 if (ondemand_peer_list_.size() == 0) {
327 _W("ondemand peer list is empty");
331 std::string header("ODL:");
332 tizen_base::Parcel parcel;
333 parcel.WriteString(header);
335 for (auto& peer : ondemand_peer_list_) {
336 if (peer->GetServiceName() != service_name ||
337 aul_app_is_running(peer->GetAppID().c_str()))
340 parcel.WriteBool(true);
341 std::vector<uint8_t> peer_raw = peer->Serialize();
342 parcel.WriteUInt32(peer_raw.size());
343 parcel.Write(peer_raw.data(), peer_raw.size());
346 parcel.WriteBool(false);