/* * Copyright (c) 2022 Huawei Device Co., Ltd. * 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 "datashare_stub.h" #include <cinttypes> #include "data_ability_observer_interface.h" #include "datashare_itypes_utils.h" #include "datashare_log.h" #include "ipc_skeleton.h" #include "ipc_types.h" #include "ishared_result_set.h" #include "datashare_operation_statement.h" #include "unistd.h" #include "string_ex.h" using namespace OHOS::DistributedShare::DataShare; namespace OHOS { namespace DataShare { constexpr int DEFAULT_NUMBER = -1; constexpr int PERMISSION_ERROR_NUMBER = -2; DataShareStub::DataShareStub() { stubFuncMap_[static_cast<uint32_t>(IDataShareInterfaceCode::CMD_GET_FILE_TYPES)] = &DataShareStub::CmdGetFileTypes; stubFuncMap_[static_cast<uint32_t>(IDataShareInterfaceCode::CMD_OPEN_FILE)] = &DataShareStub::CmdOpenFile; stubFuncMap_[static_cast<uint32_t>(IDataShareInterfaceCode::CMD_OPEN_RAW_FILE)] = &DataShareStub::CmdOpenRawFile; stubFuncMap_[static_cast<uint32_t>(IDataShareInterfaceCode::CMD_INSERT)] = &DataShareStub::CmdInsert; stubFuncMap_[static_cast<uint32_t>(IDataShareInterfaceCode::CMD_UPDATE)] = &DataShareStub::CmdUpdate; stubFuncMap_[static_cast<uint32_t>(IDataShareInterfaceCode::CMD_DELETE)] = &DataShareStub::CmdDelete; stubFuncMap_[static_cast<uint32_t>(IDataShareInterfaceCode::CMD_QUERY)] = &DataShareStub::CmdQuery; stubFuncMap_[static_cast<uint32_t>(IDataShareInterfaceCode::CMD_GET_TYPE)] = &DataShareStub::CmdGetType; stubFuncMap_[static_cast<uint32_t>(IDataShareInterfaceCode::CMD_BATCH_INSERT)] = &DataShareStub::CmdBatchInsert; stubFuncMap_[static_cast<uint32_t>(IDataShareInterfaceCode::CMD_REGISTER_OBSERVER)] = &DataShareStub::CmdRegisterObserver; stubFuncMap_[static_cast<uint32_t>(IDataShareInterfaceCode::CMD_UNREGISTER_OBSERVER)] = &DataShareStub::CmdUnregisterObserver; stubFuncMap_[static_cast<uint32_t>(IDataShareInterfaceCode::CMD_NOTIFY_CHANGE)] = &DataShareStub::CmdNotifyChange; stubFuncMap_[static_cast<uint32_t>(IDataShareInterfaceCode::CMD_NORMALIZE_URI)] = &DataShareStub::CmdNormalizeUri; stubFuncMap_[static_cast<uint32_t>(IDataShareInterfaceCode::CMD_DENORMALIZE_URI)] = &DataShareStub::CmdDenormalizeUri; stubFuncMap_[static_cast<uint32_t>(IDataShareInterfaceCode::CMD_EXECUTE_BATCH)] = &DataShareStub::CmdExecuteBatch; stubFuncMap_[static_cast<uint32_t>(IDataShareInterfaceCode::CMD_INSERT_EXT)] = &DataShareStub::CmdInsertExt; stubFuncMap_[static_cast<uint32_t>(IDataShareInterfaceCode::CMD_BATCH_UPDATE)] = &DataShareStub::CmdBatchUpdate; stubFuncMap_[static_cast<uint32_t>(IDataShareInterfaceCode::CMD_INSERT_EX)] = &DataShareStub::CmdInsertEx; stubFuncMap_[static_cast<uint32_t>(IDataShareInterfaceCode::CMD_UPDATE_EX)] = &DataShareStub::CmdUpdateEx; stubFuncMap_[static_cast<uint32_t>(IDataShareInterfaceCode::CMD_DELETE_EX)] = &DataShareStub::CmdDeleteEx; } DataShareStub::~DataShareStub() { stubFuncMap_.clear(); } int DataShareStub::OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) { std::u16string descriptor = DataShareStub::GetDescriptor(); std::u16string remoteDescriptor = data.ReadInterfaceToken(); if (descriptor != remoteDescriptor) { LOG_INFO("local descriptor is not equal to remote, localDescriptor = %{public}s, remoteDescriptor = %{public}s", Str16ToStr8(descriptor).c_str(), Str16ToStr8(remoteDescriptor).c_str()); return ERR_INVALID_STATE; } const auto &itFunc = stubFuncMap_.find(code); if (itFunc != stubFuncMap_.end()) { auto start = std::chrono::steady_clock::now(); auto ret = (this->*(itFunc->second))(data, reply); auto finish = std::chrono::steady_clock::now(); auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(finish - start); if (duration >= TIME_THRESHOLD) { auto callingPid = IPCSkeleton::GetCallingPid(); int64_t milliseconds = duration.count(); LOG_ERROR("extension time over, code:%{public}u callingPid:%{public}d, cost:%{public}" PRIi64 "ms", code, callingPid, milliseconds); } return ret; } LOG_DEBUG("remote request unhandled: %{public}d", code); return IPCObjectStub::OnRemoteRequest(code, data, reply, option); } ErrCode DataShareStub::CmdGetFileTypes(MessageParcel &data, MessageParcel &reply) { Uri uri(""); std::string mimeTypeFilter; if (!ITypesUtil::Unmarshal(data, uri, mimeTypeFilter)) { LOG_ERROR("Unmarshalling value is nullptr"); return ERR_INVALID_VALUE; } if (mimeTypeFilter.empty()) { LOG_ERROR("mimeTypeFilter is nullptr"); return ERR_INVALID_VALUE; } std::vector<std::string> types = GetFileTypes(uri, mimeTypeFilter); if (!ITypesUtil::Marshal(reply, types)) { LOG_ERROR("Marshal value is nullptr"); return ERR_INVALID_VALUE; } return E_OK; } ErrCode DataShareStub::CmdOpenFile(MessageParcel &data, MessageParcel &reply) { Uri uri(""); std::string mode; if (!ITypesUtil::Unmarshal(data, uri, mode)) { LOG_ERROR("Unmarshalling value is nullptr"); return ERR_INVALID_VALUE; } if (mode.empty()) { LOG_ERROR("mode is nullptr"); return ERR_INVALID_VALUE; } int fd = OpenFile(uri, mode); if (fd < 0) { return ERR_INVALID_DATA; } if (!reply.WriteFileDescriptor(fd)) { LOG_ERROR("fail to WriteFileDescriptor fd"); close(fd); return ERR_INVALID_VALUE; } close(fd); return E_OK; } ErrCode DataShareStub::CmdOpenRawFile(MessageParcel &data, MessageParcel &reply) { Uri uri(""); std::string mode; if (!ITypesUtil::Unmarshal(data, uri, mode)) { LOG_ERROR("Unmarshalling value is nullptr"); return ERR_INVALID_VALUE; } int fd = OpenRawFile(uri, mode); if (!ITypesUtil::Marshal(reply, fd)) { LOG_ERROR("Marshal value is nullptr"); return ERR_INVALID_VALUE; } return E_OK; } ErrCode DataShareStub::CmdInsert(MessageParcel &data, MessageParcel &reply) { Uri uri(""); DataShareValuesBucket value; if (!ITypesUtil::Unmarshal(data, uri, value)) { LOG_ERROR("Unmarshalling value is nullptr"); return ERR_INVALID_VALUE; } int index = Insert(uri, value); if (index == DEFAULT_NUMBER) { LOG_ERROR("Insert inner error"); return ERR_INVALID_VALUE; } else if (index == PERMISSION_ERROR_NUMBER) { LOG_ERROR("Insert permission error"); return ERR_PERMISSION_DENIED; } if (!reply.WriteInt32(index)) { LOG_ERROR("fail to WriteInt32 index"); return ERR_INVALID_VALUE; } return E_OK; } ErrCode DataShareStub::CmdUpdate(MessageParcel &data, MessageParcel &reply) { Uri uri(""); DataSharePredicates predicates; DataShareValuesBucket value; if (!ITypesUtil::Unmarshal(data, uri, predicates, value)) { LOG_ERROR("Unmarshalling predicates is nullptr"); return ERR_INVALID_VALUE; } int index = Update(uri, predicates, value); if (index == DEFAULT_NUMBER) { LOG_ERROR("Update inner error"); return ERR_INVALID_VALUE; } else if (index == PERMISSION_ERROR_NUMBER) { LOG_ERROR("Update permission error"); return ERR_PERMISSION_DENIED; } if (!reply.WriteInt32(index)) { LOG_ERROR("fail to WriteInt32 index"); return ERR_INVALID_VALUE; } return E_OK; } ErrCode DataShareStub::CmdBatchUpdate(OHOS::MessageParcel &data, OHOS::MessageParcel &reply) { UpdateOperations updateOperations; if (!ITypesUtil::Unmarshal(data, updateOperations)) { LOG_ERROR("Unmarshalling updateOperations is nullptr"); return ERR_INVALID_VALUE; } std::vector<BatchUpdateResult> results; int ret = BatchUpdate(updateOperations, results); if (ret != E_OK) { LOG_ERROR("BatchUpdate inner error, ret is %{public}d.", ret); return ret; } if (!ITypesUtil::Marshal(reply, results)) { LOG_ERROR("marshalling updateOperations is failed"); return ERR_INVALID_VALUE; } return E_OK; } ErrCode DataShareStub::CmdDelete(MessageParcel &data, MessageParcel &reply) { Uri uri(""); DataSharePredicates predicates; if (!ITypesUtil::Unmarshal(data, uri, predicates)) { LOG_ERROR("Unmarshalling predicates is nullptr"); return ERR_INVALID_VALUE; } int index = Delete(uri, predicates); if (index == DEFAULT_NUMBER) { LOG_ERROR("Delete inner error"); return ERR_INVALID_VALUE; } else if (index == PERMISSION_ERROR_NUMBER) { LOG_ERROR("Delete permission error"); return ERR_PERMISSION_DENIED; } if (!reply.WriteInt32(index)) { LOG_ERROR("fail to WriteInt32 index"); return ERR_INVALID_VALUE; } return E_OK; } ErrCode DataShareStub::CmdInsertEx(MessageParcel &data, MessageParcel &reply) { Uri uri(""); DataShareValuesBucket value; if (!ITypesUtil::Unmarshal(data, uri, value)) { LOG_ERROR("Unmarshalling value is nullptr"); return E_UNMARSHAL_ERROR; } auto [errCode, result] = InsertEx(uri, value); if (errCode == DEFAULT_NUMBER) { LOG_ERROR("Insert inner error"); return ERR_INVALID_VALUE; } else if (errCode == PERMISSION_ERROR_NUMBER) { LOG_ERROR("Insert permission error"); return ERR_PERMISSION_DENIED; } if (!ITypesUtil::Marshal(reply, errCode, result)) { LOG_ERROR("Marshal value is nullptr"); return E_MARSHAL_ERROR; } return E_OK; } ErrCode DataShareStub::CmdUpdateEx(MessageParcel &data, MessageParcel &reply) { Uri uri(""); DataSharePredicates predicates; DataShareValuesBucket value; if (!ITypesUtil::Unmarshal(data, uri, predicates, value)) { LOG_ERROR("Unmarshalling predicates is nullptr"); return E_UNMARSHAL_ERROR; } auto [errCode, result] = UpdateEx(uri, predicates, value); if (errCode == DEFAULT_NUMBER) { LOG_ERROR("Update inner error"); return ERR_INVALID_VALUE; } else if (errCode == PERMISSION_ERROR_NUMBER) { LOG_ERROR("Update permission error"); return ERR_PERMISSION_DENIED; } if (!ITypesUtil::Marshal(reply, errCode, result)) { LOG_ERROR("Marshal value is nullptr"); return E_MARSHAL_ERROR; } return E_OK; } ErrCode DataShareStub::CmdDeleteEx(MessageParcel &data, MessageParcel &reply) { Uri uri(""); DataSharePredicates predicates; if (!ITypesUtil::Unmarshal(data, uri, predicates)) { LOG_ERROR("Unmarshalling predicates is nullptr"); return E_UNMARSHAL_ERROR; } auto [errCode, result] = DeleteEx(uri, predicates); if (errCode == DEFAULT_NUMBER) { LOG_ERROR("Delete inner error"); return ERR_INVALID_VALUE; } else if (errCode == PERMISSION_ERROR_NUMBER) { LOG_ERROR("Delete permission error"); return ERR_PERMISSION_DENIED; } if (!ITypesUtil::Marshal(reply, errCode, result)) { LOG_ERROR("Marshal value is nullptr"); return E_MARSHAL_ERROR; } return E_OK; } ErrCode DataShareStub::CmdQuery(MessageParcel &data, MessageParcel &reply) { Uri uri(""); DataSharePredicates predicates; std::vector<std::string> columns; if (!ITypesUtil::Unmarshal(data, uri, predicates, columns)) { LOG_ERROR("Unmarshalling predicates is nullptr"); return ERR_INVALID_VALUE; } DatashareBusinessError businessError; auto resultSet = Query(uri, predicates, columns, businessError); auto result = ISharedResultSet::WriteToParcel(std::move(resultSet), reply); reply.WriteInt32(businessError.GetCode()); reply.WriteString(businessError.GetMessage()); if (result == nullptr) { LOG_ERROR("!resultSet->Marshalling(reply)"); return ERR_INVALID_VALUE; } return E_OK; } ErrCode DataShareStub::CmdGetType(MessageParcel &data, MessageParcel &reply) { Uri uri(""); if (!ITypesUtil::Unmarshal(data, uri)) { LOG_ERROR("Unmarshalling predicates is nullptr"); return ERR_INVALID_VALUE; } std::string type = GetType(uri); if (!reply.WriteString(type)) { LOG_ERROR("fail to WriteString type"); return ERR_INVALID_VALUE; } return E_OK; } ErrCode DataShareStub::CmdBatchInsert(MessageParcel &data, MessageParcel &reply) { Uri uri(""); std::vector<DataShareValuesBucket> values; if (!ITypesUtil::Unmarshal(data, uri, values)) { LOG_ERROR("Unmarshalling predicates is nullptr"); return ERR_INVALID_VALUE; } int ret = BatchInsert(uri, values); if (ret == DEFAULT_NUMBER) { LOG_ERROR("BatchInsert inner error"); return ERR_INVALID_VALUE; } else if (ret == PERMISSION_ERROR_NUMBER) { LOG_ERROR("BatchInsert permission error"); return ERR_PERMISSION_DENIED; } if (!reply.WriteInt32(ret)) { LOG_ERROR("fail to WriteInt32 ret"); return ERR_INVALID_VALUE; } return E_OK; } ErrCode DataShareStub::CmdRegisterObserver(MessageParcel &data, MessageParcel &reply) { Uri uri(""); sptr<IRemoteObject> observer; if (!ITypesUtil::Unmarshal(data, uri, observer)) { LOG_ERROR("Unmarshalling predicates is nullptr"); return ERR_INVALID_VALUE; } auto obServer = iface_cast<AAFwk::IDataAbilityObserver>(observer); if (obServer == nullptr) { LOG_ERROR("obServer is nullptr"); return ERR_INVALID_VALUE; } bool ret = RegisterObserver(uri, obServer); if (!reply.WriteInt32(ret)) { LOG_ERROR("fail to WriteInt32 ret"); return ERR_INVALID_VALUE; } return E_OK; } ErrCode DataShareStub::CmdUnregisterObserver(MessageParcel &data, MessageParcel &reply) { Uri uri(""); sptr<IRemoteObject> observer; if (!ITypesUtil::Unmarshal(data, uri, observer)) { LOG_ERROR("Unmarshalling predicates is nullptr"); return ERR_INVALID_VALUE; } auto obServer = iface_cast<AAFwk::IDataAbilityObserver>(observer); if (obServer == nullptr) { LOG_ERROR("obServer is nullptr"); return ERR_INVALID_VALUE; } bool ret = UnregisterObserver(uri, obServer); if (!reply.WriteInt32(ret)) { LOG_ERROR("fail to WriteInt32 ret"); return ERR_INVALID_VALUE; } return E_OK; } ErrCode DataShareStub::CmdNotifyChange(MessageParcel &data, MessageParcel &reply) { Uri uri(""); if (!ITypesUtil::Unmarshal(data, uri)) { LOG_ERROR("Unmarshalling predicates is nullptr"); return ERR_INVALID_VALUE; } bool ret = NotifyChange(uri); if (!reply.WriteInt32(ret)) { LOG_ERROR("fail to WriteInt32 ret"); return ERR_INVALID_VALUE; } return E_OK; } ErrCode DataShareStub::CmdNormalizeUri(MessageParcel &data, MessageParcel &reply) { Uri uri(""); if (!ITypesUtil::Unmarshal(data, uri)) { LOG_ERROR("Unmarshalling predicates is nullptr"); return ERR_INVALID_VALUE; } auto ret = NormalizeUri(uri); if (!ITypesUtil::Marshal(reply, ret)) { LOG_ERROR("Write to message parcel failed!"); return ERR_INVALID_VALUE; } return E_OK; } ErrCode DataShareStub::CmdDenormalizeUri(MessageParcel &data, MessageParcel &reply) { Uri uri(""); if (!ITypesUtil::Unmarshal(data, uri)) { LOG_ERROR("Unmarshalling predicates is nullptr"); return ERR_INVALID_VALUE; } auto ret = DenormalizeUri(uri); if (!ITypesUtil::Marshal(reply, ret)) { LOG_ERROR("Write to message parcel failed!"); return ERR_INVALID_VALUE; } return E_OK; } ErrCode DataShareStub::CmdExecuteBatch(MessageParcel &data, MessageParcel &reply) { std::vector<OperationStatement> statements; ExecResultSet result; if (!ITypesUtil::Unmarshal(data, statements)) { LOG_ERROR("Unmarshalling OperationStatement failed"); return ERR_INVALID_VALUE; } auto ret = ExecuteBatch(statements, result); if (ret == DEFAULT_NUMBER) { LOG_ERROR("ExecuteBatch error"); return ERR_INVALID_VALUE; } if (!ITypesUtil::Marshal(reply, result)) { LOG_ERROR("fail to write result"); return ERR_INVALID_VALUE; } return E_OK; } ErrCode DataShareStub::CmdInsertExt(MessageParcel &data, MessageParcel &reply) { Uri uri(""); DataShareValuesBucket value; if (!ITypesUtil::Unmarshal(data, uri, value)) { LOG_ERROR("Unmarshalling value is nullptr"); return ERR_INVALID_VALUE; } std::string result; int index = InsertExt(uri, value, result); if (index == DEFAULT_NUMBER) { LOG_ERROR("Insert inner error"); return ERR_INVALID_VALUE; } if (!ITypesUtil::Marshal(reply, index, result)) { LOG_ERROR("fail to write result"); return ERR_INVALID_VALUE; } return E_OK; } int DataShareStub::ExecuteBatch(const std::vector<OperationStatement> &statements, ExecResultSet &result) { return 0; } int DataShareStub::InsertExt(const Uri &uri, const DataShareValuesBucket &value, std::string &result) { return 0; } int DataShareStub::BatchUpdate(const UpdateOperations &operations, std::vector<BatchUpdateResult> &results) { return 0; } std::pair<int32_t, int32_t> DataShareStub::InsertEx(const Uri &uri, const DataShareValuesBucket &value) { return std::make_pair(0, 0); } std::pair<int32_t, int32_t> DataShareStub::UpdateEx(const Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value) { return std::make_pair(0, 0); } std::pair<int32_t, int32_t> DataShareStub::DeleteEx(const Uri &uri, const DataSharePredicates &predicates) { return std::make_pair(0, 0); } } // namespace DataShare } // namespace OHOS