diff --git a/BUILD.gn b/BUILD.gn index 1b647149015cca09898eec6803d9ed3b494d6fa3..5729edd6c7201a05a2528b28df1815d017f43192 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -48,4 +48,4 @@ group("tgt_backup_tests") { "tests/moduletests", "tests/unittests", ] -} +} \ No newline at end of file diff --git a/services/backup_sa/BUILD.gn b/services/backup_sa/BUILD.gn index d589c50d61658aebc83f3f42b224eb935b04e540..cf8de03caa5d5ff379f5dc9c33600293d03a1ac1 100644 --- a/services/backup_sa/BUILD.gn +++ b/services/backup_sa/BUILD.gn @@ -16,6 +16,7 @@ import("//foundation/filemanagement/app_file_service/backup.gni") ohos_shared_library("backup_sa") { sources = [ + "src/module_app_gallery/app_gallery_dispose_proxy.cpp", "src/module_external/bms_adapter.cpp", "src/module_external/inner_receiver_impl.cpp", "src/module_external/sms_adapter.cpp", diff --git a/services/backup_sa/include/module_app_gallery/app_gallery_dispose_proxy.h b/services/backup_sa/include/module_app_gallery/app_gallery_dispose_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..bebbf578aab44692f61180538350f98993254bbb --- /dev/null +++ b/services/backup_sa/include/module_app_gallery/app_gallery_dispose_proxy.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) Huawei Device Co., Ltd. 2023. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_APP_GALLERY_DISPOSE_PROXY_H +#define OHOS_FILEMGMT_BACKUP_APP_GALLERY_DISPOSE_PROXY_H + +#include +#include + +#include + +#include "i_appgallery_service.h" + +namespace OHOS::FileManagement::Backup { +enum class DisposeErr { + OK = 0, + CONN_FAIL = 1, + IPC_FAIL = 2, + REQUEST_FAIL = 3, +}; + +class AppGalleryDisposeProxy : public IRemoteStub { +public: + DISALLOW_COPY_AND_MOVE(AppGalleryDisposeProxy); + + AppGalleryDisposeProxy(); + ~AppGalleryDisposeProxy(); + + static sptr GetInstance(); + + DisposeErr StartBackup(const std::string &bundleName); + DisposeErr EndBackup(const std::string &bundleName); + DisposeErr StartRestore(const std::string &bundleName); + DisposeErr EndRestore(const std::string &bundleName); + + static std::condition_variable conditionVal_; + static std::string abilityName; + static std::mutex appRemoteObjLock_; + static std::mutex connectMutex; + static sptr appRemoteObj_; + +private: + DisposeErr DoDispose(const std::string &bundleName, DisposeOperation disposeOperation); + +private: + static std::mutex instanceLock_; + static std::mutex conditionMutex_; + static sptr appGalleryDisposeProxyInstance_; +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_APP_GALLERY_DISPOSE_PROXY_H \ No newline at end of file diff --git a/services/backup_sa/include/module_app_gallery/app_gallery_service_connection.h b/services/backup_sa/include/module_app_gallery/app_gallery_service_connection.h new file mode 100644 index 0000000000000000000000000000000000000000..1e1eb7dfc8db055c04d28b82aa7eabdbd9475c2c --- /dev/null +++ b/services/backup_sa/include/module_app_gallery/app_gallery_service_connection.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) Huawei Device Co., Ltd. 2023. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_APP_GALLERY_SERVICE_CONNECTION_H +#define OHOS_FILEMGMT_BACKUP_APP_GALLERY_SERVICE_CONNECTION_H + +#include +#include +#include + +#include "ability_manager_client.h" +#include "ability_connect_callback_stub.h" +#include "want.h" + +#include "i_appgallery_service.h" +#include "filemgmt_libhilog.h" + +namespace OHOS::FileManagement::Backup { +using namespace OHOS::AppExecFwk; +const std::string APP_GALLERY_PKG_NAME = "com.huawei.hmsapp.appgallery"; +const int32_t CONNECT_TIME = 5; + +template class AppGralleryConnection : public AbilityConnectionStub { +public: + void OnAbilityConnectDone(const AppExecFwk::ElementName &element, const sptr &remoteObject, + int resultCode) + { + std::string uri = element.GetURI(); + HILOGI("OnAbilityConnectDone, uri = %{public}s", uri.c_str()); + T::appRemoteObj_ = remoteObject; + T::conditionVal_.notify_one(); + } + + void OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode) + { + std::string uri = element.GetURI(); + HILOGI("OnAbilityDisconnectDone, uri = %{public}s", uri.c_str()); + T::appRemoteObj_ = nullptr; + } +}; + +template bool ConnectExtAbility() +{ + HILOGI("ConnectExtAbility called"); + std::lock_guard autoLock(T::appRemoteObjLock_); + if (T::appRemoteObj_ != nullptr) { + return true; + } + + Want want; + want.SetElementName(APP_GALLERY_PKG_NAME, T::abilityName); + sptr connect = new AppGralleryConnection(); + auto ret = AbilityManagerClient::GetInstance()->ConnectAbility(want, connect, -1); + + std::unique_lock uniqueLock(T::connectMutex); + T::conditionVal_.wait_for(uniqueLock, std::chrono::seconds(CONNECT_TIME)); + if (ret != IAppGalleryService::ERR_OK || T::appRemoteObj_ == nullptr) { + HILOGI("ConnectExtAbility failed, ret=%{public}d", ret); + T::appRemoteObj_ = nullptr; + return false; + } + HILOGI("ConnectExtAbility success, ret=%{public}d", ret); + return true; +}; +} // namespace OHOS::FileManagement::Backup +#endif // OHOS_FILEMGMT_BACKUP_APP_GALLERY_SERVICE_CONNECTION_H \ No newline at end of file diff --git a/services/backup_sa/include/module_app_gallery/i_appgallery_service.h b/services/backup_sa/include/module_app_gallery/i_appgallery_service.h new file mode 100644 index 0000000000000000000000000000000000000000..fdff003f02a06dedef830939e8ca70b12406decf --- /dev/null +++ b/services/backup_sa/include/module_app_gallery/i_appgallery_service.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) Huawei Device Co., Ltd. 2023. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_FILEMGMT_BACKUP_I_APP_GALLERY_SERVICE_H +#define OHOS_FILEMGMT_BACKUP_I_APP_GALLERY_SERVICE_H + +#include + +#include "iremote_proxy.h" + +namespace OHOS::FileManagement::Backup { +class IAppGalleryService: public OHOS::IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.FileManagement.Backup.IAppGalleryService"); + + enum class DisposeOperation { + START_RESTORE = 3, + END_RESTORE = 4, + START_BACKUP = 5, + END_BACKUP = 6, + }; + + enum Errcode { + ERR_BASE = (-99), + ERR_FAILED = (-1), + ERR_PERMISSION_DENIED = (-2), + ERR_OK = 0, + }; +}; +} // namespace OHOS::FileManagement::Backup + +#endif // OHOS_FILEMGMT_BACKUP_I_APP_GALLERY_SERVICE_H \ No newline at end of file diff --git a/services/backup_sa/src/module_app_gallery/app_gallery_dispose_proxy.cpp b/services/backup_sa/src/module_app_gallery/app_gallery_dispose_proxy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..03583076ba1be19e56b0e3191e3717cf0c0cc789 --- /dev/null +++ b/services/backup_sa/src/module_app_gallery/app_gallery_dispose_proxy.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (c) Huawei Device Co., Ltd. 2023. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "message_parcel.h" +#include "nlohmann/json.hpp" +#include "want.h" + +#include "module_app_gallery/app_gallery_dispose_proxy.h" +#include "module_app_gallery/app_gallery_service_connection.h" +#include "filemgmt_libhilog.h" + +namespace OHOS::FileManagement::Backup { +using namespace std; + +mutex AppGalleryDisposeProxy::instanceLock_; +mutex AppGalleryDisposeProxy::conditionMutex_; + +string AppGalleryDisposeProxy::abilityName = "AppFoundationServiceExtensionAbility"; +sptr AppGalleryDisposeProxy::appRemoteObj_; +condition_variable AppGalleryDisposeProxy::conditionVal_; +mutex AppGalleryDisposeProxy::appRemoteObjLock_; +mutex AppGalleryDisposeProxy::connectMutex; +sptr AppGalleryDisposeProxy::appGalleryDisposeProxyInstance_; + +AppGalleryDisposeProxy::AppGalleryDisposeProxy() +{ + HILOGI("AppGalleryDisposeProxy constructor"); +} + +AppGalleryDisposeProxy::~AppGalleryDisposeProxy() +{ + HILOGI("AppGalleryDisposeProxy destructor"); +} + +sptr AppGalleryDisposeProxy::GetInstance() +{ + if (appGalleryDisposeProxyInstance_ == nullptr) { + lock_guard autoLock(instanceLock_); + if (appGalleryDisposeProxyInstance_ == nullptr) { + appGalleryDisposeProxyInstance_ = new AppGalleryDisposeProxy; + } + } + + return appGalleryDisposeProxyInstance_; +} + +DisposeErr AppGalleryDisposeProxy::StartBackup(const std::string &bundleName) +{ + HILOGI("StartBackup, app %{public}s", bundleName.c_str()); + return DoDispose(bundleName, DisposeOperation::START_BACKUP); +} + +DisposeErr AppGalleryDisposeProxy::EndBackup(const std::string &bundleName) +{ + HILOGI("EndBackup, app %{public}s", bundleName.c_str()); + return DoDispose(bundleName, DisposeOperation::END_BACKUP); +} + +DisposeErr AppGalleryDisposeProxy::StartRestore(const std::string &bundleName) +{ + HILOGI("StartRestore, app %{public}s", bundleName.c_str()); + return DoDispose(bundleName, DisposeOperation::START_RESTORE); +} + +DisposeErr AppGalleryDisposeProxy::EndRestore(const std::string &bundleName) +{ + HILOGI("EndRestore, app %{public}s", bundleName.c_str()); + return DoDispose(bundleName, DisposeOperation::END_RESTORE); +} + +DisposeErr AppGalleryDisposeProxy::DoDispose(const std::string &bundleName, DisposeOperation disposeOperation) +{ + HILOGI("DoDispose, app %{public}s, operation %{public}d", bundleName.c_str(), disposeOperation); + if (!ConnectExtAbility() || appRemoteObj_ == nullptr) { + HILOGI("Can not connect to %{public}s", bundleName.c_str()); + return DisposeErr::CONN_FAIL; + } + + MessageParcel data; + if (!data.WriteString16(Str8ToStr16(bundleName))) { + HILOGI("write ownerInfo and bundleName failed"); + return DisposeErr::IPC_FAIL; + } + + if (!data.WriteRemoteObject(this)) { + HILOGI("write RemoteObject failed"); + return DisposeErr::IPC_FAIL; + } + + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + auto ret = appRemoteObj_->SendRequest(static_cast(disposeOperation), data, reply, option); + if (ret != ERR_NONE) { + HILOGI("SendRequest error, code=%{public}d, bundleName=%{public}s", disposeOperation, bundleName.c_str()); + return DisposeErr::REQUEST_FAIL; + } + + HILOGI("SendRequest error, code=%{public}d, bundleName=%{public}s", disposeOperation, bundleName.c_str()); + return DisposeErr::OK; +} + +} // namespace OHOS::FileManagement::Backup \ No newline at end of file diff --git a/services/backup_sa/src/module_ipc/service_reverse_proxy.cpp b/services/backup_sa/src/module_ipc/service_reverse_proxy.cpp index 6dd0e4100d6eef9f74a4a1c691db82f20cb1af21..4a18640838a00b8c78fc5e170a82e11696f1ca8d 100644 --- a/services/backup_sa/src/module_ipc/service_reverse_proxy.cpp +++ b/services/backup_sa/src/module_ipc/service_reverse_proxy.cpp @@ -15,6 +15,7 @@ #include "module_ipc/service_reverse_proxy.h" +#include "module_app_gallery/app_gallery_dispose_proxy.h" #include "b_error/b_error.h" #include "b_error/b_excep_utils.h" #include "filemgmt_libhilog.h" @@ -114,6 +115,9 @@ void ServiceReverseProxy::RestoreOnBundleStarted(int32_t errCode, string bundleN err != ERR_OK) { throw BError(BError::Codes::SA_BROKEN_IPC, to_string(err)); } + AppGalleryDisposeProxy appGalleryDisposeProxy; + DisposeErr disposeErr = appGalleryDisposeProxy.StartRestore(bundleName); + HILOGI("AppGalleryDisposeProxy StartRestore, code=%{public}d, bundleName=%{public}s", disposeErr, bundleName.c_str()); } void ServiceReverseProxy::RestoreOnBundleFinished(int32_t errCode, string bundleName) @@ -133,6 +137,10 @@ void ServiceReverseProxy::RestoreOnBundleFinished(int32_t errCode, string bundle err != ERR_OK) { throw BError(BError::Codes::SA_BROKEN_IPC, to_string(err)); } + + AppGalleryDisposeProxy appGalleryDisposeProxy; + DisposeErr disposeErr = appGalleryDisposeProxy.EndRestore(bundleName); + HILOGI("AppGalleryDisposeProxy EndRestore, code=%{public}d, bundleName=%{public}s", disposeErr, bundleName.c_str()); } void ServiceReverseProxy::RestoreOnAllBundlesFinished(int32_t errCode) diff --git a/utils/src/b_error/b_excep_utils.cpp b/utils/src/b_error/b_excep_utils.cpp index 032f51b34e171014a63c918a4c6d139f017019b5..9af76541fac1d2f126d82a3a6c17647da6ae9361 100644 --- a/utils/src/b_error/b_excep_utils.cpp +++ b/utils/src/b_error/b_excep_utils.cpp @@ -16,6 +16,13 @@ #include "b_error/b_excep_utils.h" #include +#include +#ifdef _WIN32 +#include +#else +#include +#include +#endif #include "b_resources/b_constants.h" #include "cxx.h" @@ -27,11 +34,10 @@ using namespace std; void BExcepUltils::VerifyPath(const string_view &path, bool isExtension) { try { - auto ret = canonicalize(path.data()); - string absPath = ret.c_str(); + string absPath = BExcepUltils::Canonicalize(path); if (isExtension && absPath.find(string(BConstants::PATH_BUNDLE_BACKUP_HOME) - .append(BConstants::SA_BUNDLE_BACKUP_RESTORE)) == std::string::npos) { + .append(BConstants::SA_BUNDLE_BACKUP_RESTORE)) == string::npos) { throw BError(BError::Codes::EXT_INVAL_ARG, "Invalid path, not in backup restore path"); } } catch (const rust::Error &e) { @@ -42,8 +48,21 @@ void BExcepUltils::VerifyPath(const string_view &path, bool isExtension) string BExcepUltils::Canonicalize(const string_view &path) { try { - auto ret = canonicalize(path.data()); - return ret.c_str(); + char full_path[PATH_MAX] = {0}; + //1.转换绝对路径到dir +#ifdef _WIN32 + _fullpath(full_path, path.data(), PATH_MAX); +#else + realpath(path.data(), full_path); +#endif + //2.替换绝对路径中的'\'为'/' + //因为上述方法转换出来的绝对路径之间会以'\'分隔,例如“C:\user\desktop”,字符串处理遇到'\'一般会报错,下面一行代码将'\'全部替换为'/' + // for (int i = 0; full_path[i] != 0 && i < MAX_PATH_LEN; i++) { + // if (full_path[i] == 92) { + // full_path[i] = '/'; + // } + // } + return string(full_path); } catch (const rust::Error &e) { throw BError(BError::Codes::EXT_INVAL_ARG, "Invalid path"); }