1 /*
2 * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "network/softbus/softbus_session_listener.h"
17
18 #include "dfs_error.h"
19 #include "network/softbus/softbus_session_pool.h"
20 #include "os_account_manager.h"
21 #include "sandbox_helper.h"
22 #include "string"
23 #include "uri.h"
24 #include "utils_directory.h"
25 #include "utils_log.h"
26
27 namespace OHOS {
28 namespace Storage {
29 namespace DistributedFile {
30 constexpr size_t MAX_SIZE = 500;
31 constexpr int32_t DEFAULT_USER_ID = 100;
32 const std::string FILE_SCHEMA = "file://";
33 const std::string DOCS = "docs";
34 const std::string NETWORK_ID = "?networkid=";
35 const std::string FILE_SEPARATOR = "/";
36 const std::string DISTRIBUTED_PATH = "distributedfiles/.remote_share/";
37 const std::string MEDIA = "media";
38 using namespace OHOS::AppFileService;
39 using namespace OHOS::FileManagement;
40
QueryActiveUserId()41 int32_t SoftBusSessionListener::QueryActiveUserId()
42 {
43 std::vector<int32_t> ids;
44 ErrCode errCode = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
45 if (errCode != FileManagement::ERR_OK || ids.empty()) {
46 LOGE("Query active userid failed, errCode: %{public}d, ", errCode);
47 return DEFAULT_USER_ID;
48 }
49 return ids[0];
50 }
51
GetFileName(const std::vector<std::string> & fileList,const std::string & path,const std::string & dstPath)52 std::vector<std::string> SoftBusSessionListener::GetFileName(const std::vector<std::string> &fileList,
53 const std::string &path,
54 const std::string &dstPath)
55 {
56 std::vector<std::string> tmp;
57 if (Utils::IsFolder(path)) {
58 for (const auto &it : fileList) {
59 tmp.push_back(it.substr(path.size() + 1));
60 }
61 return tmp;
62 }
63 if (dstPath.find("??") == 0) {
64 auto pos = dstPath.rfind("/");
65 tmp.push_back(dstPath.substr(pos + 1));
66 } else {
67 auto pos = path.rfind("/");
68 tmp.push_back(path.substr(pos + 1));
69 }
70 return tmp;
71 }
72
OnSessionOpened(int32_t sessionId,PeerSocketInfo info)73 void SoftBusSessionListener::OnSessionOpened(int32_t sessionId, PeerSocketInfo info)
74 {
75 LOGI("OnSessionOpened sessionId = %{public}d", sessionId);
76 if (!SoftBusHandler::IsSameAccount(info.networkId)) {
77 LOGI("The source and sink device is not same account, not support.");
78 Shutdown(sessionId);
79 return;
80 }
81 std::string sessionName = info.name;
82 SoftBusSessionPool::SessionInfo sessionInfo;
83 auto ret = SoftBusSessionPool::GetInstance().GetSessionInfo(sessionName, sessionInfo);
84 if (!ret) {
85 LOGE("GetSessionInfo failed");
86 return;
87 }
88
89 std::string physicalPath = GetRealPath(sessionInfo.srcUri);
90 if (physicalPath.empty()) {
91 LOGE("GetRealPath failed");
92 return;
93 }
94
95 auto fileList = OHOS::Storage::DistributedFile::Utils::GetFilePath(physicalPath);
96 if (fileList.empty()) {
97 LOGE("GetFilePath failed or file is empty");
98 return;
99 }
100
101 const char *src[MAX_SIZE] = {};
102 for (size_t i = 0; i < fileList.size() && fileList.size() < MAX_SIZE; i++) {
103 src[i] = fileList.at(i).c_str();
104 }
105
106 auto fileNameList = GetFileName(fileList, physicalPath, sessionInfo.dstPath);
107 if (fileNameList.empty()) {
108 LOGE("GetFileName failed or file is empty");
109 return;
110 }
111 const char *dst[MAX_SIZE] = {};
112 for (size_t i = 0; i < fileNameList.size() && fileList.size() < MAX_SIZE; i++) {
113 dst[i] = fileNameList.at(i).c_str();
114 }
115 LOGI("Enter SendFile.");
116 ret = ::SendFile(sessionId, src, dst, static_cast<uint32_t>(fileList.size()));
117 if (ret != E_OK) {
118 LOGE("SendFile failed, sessionId = %{public}d", sessionId);
119 RadarDotsSendFile("OpenSession", sessionName, sessionName, ret, Utils::StageRes::STAGE_FAIL);
120 }
121 SoftBusSessionPool::GetInstance().DeleteSessionInfo(sessionName);
122 RadarDotsSendFile("OpenSession", sessionName, sessionName, ret, Utils::StageRes::STAGE_SUCCESS);
123 }
124
OnSessionClosed(int32_t sessionId,ShutdownReason reason)125 void SoftBusSessionListener::OnSessionClosed(int32_t sessionId, ShutdownReason reason)
126 {
127 (void)reason;
128 std::string sessionName = "";
129 sessionName = SoftBusHandler::GetSessionName(sessionId);
130 LOGI("OnSessionClosed, sessionId = %{public}d", sessionId);
131 SoftBusHandler::GetInstance().CloseSessionWithSessionName(sessionName);
132 }
133
GetLocalUri(const std::string & uri)134 std::string SoftBusSessionListener::GetLocalUri(const std::string &uri)
135 {
136 auto pos = uri.find(NETWORK_ID);
137 if (pos == std::string::npos) {
138 return "";
139 }
140 return uri.substr(0, pos);
141 }
142
GetBundleName(const std::string & uri)143 std::string SoftBusSessionListener::GetBundleName(const std::string &uri)
144 {
145 auto pos = uri.find(FILE_SCHEMA);
146 if (pos == std::string::npos) {
147 return "";
148 }
149 auto tmpUri = uri.substr(pos + FILE_SCHEMA.size());
150 if (tmpUri.empty()) {
151 return "";
152 }
153 auto bundleNamePos = tmpUri.find(FILE_SEPARATOR);
154 if (bundleNamePos == std::string::npos) {
155 return "";
156 }
157 return tmpUri.substr(0, bundleNamePos);
158 }
159
GetSandboxPath(const std::string & uri)160 std::string SoftBusSessionListener::GetSandboxPath(const std::string &uri)
161 {
162 auto pos = uri.find(DISTRIBUTED_PATH);
163 if (pos == std::string::npos) {
164 return "";
165 }
166 return uri.substr(pos + DISTRIBUTED_PATH.size());
167 }
168
GetRealPath(const std::string & srcUri)169 std::string SoftBusSessionListener::GetRealPath(const std::string &srcUri)
170 {
171 std::string localUri = GetLocalUri(srcUri);
172 if (localUri.empty()) {
173 LOGE("get local uri failed.");
174 return localUri;
175 }
176 std::string physicalPath;
177 if (SandboxHelper::GetPhysicalPath(localUri, std::to_string(QueryActiveUserId()), physicalPath) != E_OK) {
178 LOGE("GetPhysicalPath failed, invalid uri, physicalPath = %{public}s", GetAnonyString(physicalPath).c_str());
179 return "";
180 }
181 if (physicalPath.empty() || physicalPath.size() >= PATH_MAX) {
182 LOGE("PhysicalPath.size() = %{public}zu", physicalPath.size());
183 return "";
184 }
185 char realPath[PATH_MAX] = { 0x00 };
186 if (realpath(physicalPath.c_str(), realPath) == nullptr) {
187 LOGE("realpath failed, error: %{public}d, path is %{public}s", errno, GetAnonyString(physicalPath).c_str());
188 return "";
189 }
190 return physicalPath;
191 }
192 } // namespace DistributedFile
193 } // namespace Storage
194 } // namespace OHOS