1 /*
2 * Copyright (C) 2022 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 #define MLOG_TAG "MtpEvent"
16 #include "mtp_event.h"
17 #include <numeric>
18 #include <unistd.h>
19 #include "media_log.h"
20 #include "media_mtp_utils.h"
21 #include "mtp_dfx_reporter.h"
22 #include "mtp_packet.h"
23 #include "mtp_packet_tools.h"
24 #include "mtp_media_library.h"
25
26 using namespace std;
27 namespace OHOS {
28 namespace Media {
MtpEvent(const std::shared_ptr<MtpOperationContext> & context)29 MtpEvent::MtpEvent(const std::shared_ptr<MtpOperationContext> &context)
30 {
31 CHECK_AND_RETURN_LOG(context != nullptr, "MtpEvent failed, context is nullptr");
32
33 if (context != nullptr) {
34 mtpContextPtr_ = context;
35 }
36 }
37
~MtpEvent()38 MtpEvent::~MtpEvent()
39 {
40 }
41
SendObjectAdded(const std::string & path)42 void MtpEvent::SendObjectAdded(const std::string &path)
43 {
44 CHECK_AND_RETURN_LOG(mtpContextPtr_ != nullptr, "SendObjectAdded failed, mtpContextPtr_ is nullptr");
45
46 handleptr_ = make_shared<MtpOperationUtils>(mtpContextPtr_);
47 CHECK_AND_RETURN_LOG(handleptr_ != nullptr, "SendObjectAdded failed, handleptr_ is nullptr");
48
49 uint32_t handle{0};
50 int i{0};
51 while (i < MTP_SEND_ADD_TIMES) {
52 if (handleptr_->GetHandleByPaths(path, handle) == E_SUCCESS) {
53 mtpContextPtr_->eventHandle = handle;
54 SendEvent(MTP_EVENT_OBJECT_ADDED_CODE);
55 return;
56 }
57 i++;
58 usleep(MTP_SEND_ADD);
59 MEDIA_DEBUG_LOG("MtpEvent::sendObjectAdded try %{public}d times", i);
60 }
61 }
62
SendObjectRemoved(const std::string & path)63 void MtpEvent::SendObjectRemoved(const std::string &path)
64 {
65 CHECK_AND_RETURN_LOG(mtpContextPtr_ != nullptr, "SendObjectRemoved failed, mtpContextPtr_ is nullptr");
66
67 handleptr_ = make_shared<MtpOperationUtils>(mtpContextPtr_);
68 CHECK_AND_RETURN_LOG(handleptr_ != nullptr, "SendObjectRemoved failed, handleptr_ is nullptr");
69
70 uint32_t handle{0};
71 int i{0};
72 while (i < MTP_SEND_ADD_TIMES) {
73 if (handleptr_->GetHandleByPaths(path, handle) == E_SUCCESS) {
74 mtpContextPtr_->eventHandle = handle;
75 SendEvent(MTP_EVENT_OBJECT_REMOVED_CODE);
76 MtpMediaLibrary::GetInstance()->ObserverDeletePathToMap(path);
77 return;
78 }
79 i++;
80 usleep(MTP_SEND_ADD);
81 MEDIA_DEBUG_LOG("MtpEvent::sendObjectRemoved try %{public}d times", i);
82 }
83 }
84
SendObjectRemovedByHandle(uint32_t handle)85 void MtpEvent::SendObjectRemovedByHandle(uint32_t handle)
86 {
87 CHECK_AND_RETURN_LOG(mtpContextPtr_ != nullptr, "SendObjectRemovedByHandle failed, mtpContextPtr_ is nullptr");
88 mtpContextPtr_->eventHandle = handle;
89 SendEvent(MTP_EVENT_OBJECT_REMOVED_CODE);
90 }
91
SendObjectInfoChanged(const std::string & path)92 void MtpEvent::SendObjectInfoChanged(const std::string &path)
93 {
94 CHECK_AND_RETURN_LOG(mtpContextPtr_ != nullptr, "SendObjectInfoChanged failed, mtpContextPtr_ is nullptr");
95
96 handleptr_ = make_shared<MtpOperationUtils>(mtpContextPtr_);
97 CHECK_AND_RETURN_LOG(handleptr_ != nullptr, "SendObjectInfoChanged failed, handleptr_ is nullptr");
98
99 uint32_t handle{0};
100 if (handleptr_->GetHandleByPaths(path, handle) == E_SUCCESS) {
101 mtpContextPtr_->eventHandle = handle;
102 SendEvent(MTP_EVENT_OBJECT_INFO_CHANGED_CODE);
103 }
104 }
105
SendDevicePropertyChanged()106 void MtpEvent::SendDevicePropertyChanged()
107 {
108 CHECK_AND_RETURN_LOG(mtpContextPtr_ != nullptr, "SendDevicePropertyChanged failed, mtpContextPtr_ is nullptr");
109
110 mtpContextPtr_->eventProperty = MTP_DEVICE_PROPERTY_BATTERY_LEVEL_CODE;
111 SendEvent(MTP_EVENT_DEVICE_PROP_CHANGED_CODE);
112 }
113
SendStoreAdded(const std::string & fsUuid)114 void MtpEvent::SendStoreAdded(const std::string &fsUuid)
115 {
116 CHECK_AND_RETURN_LOG(mtpContextPtr_ != nullptr, "SendStoreAdded mtpContextPtr_ is nullptr");
117 handleptr_ = make_shared<MtpOperationUtils>(mtpContextPtr_);
118 CHECK_AND_RETURN_LOG(handleptr_ != nullptr, "SendStoreAdded handleptr_ is nullptr");
119
120 uint32_t storageId{0};
121 CHECK_AND_RETURN_LOG(handleptr_->TryAddExternalStorage(fsUuid, storageId), "TryAddExternalStorage fail");
122 MEDIA_INFO_LOG("SendStoreAdded storageId[%{public}d]", storageId);
123 mtpContextPtr_->storageInfoID = storageId;
124 SendEvent(MTP_EVENT_STORE_ADDED_CODE);
125 }
126
SendStoreRemoved(const std::string & fsUuid)127 void MtpEvent::SendStoreRemoved(const std::string &fsUuid)
128 {
129 CHECK_AND_RETURN_LOG(mtpContextPtr_ != nullptr, "SendStoreRemoved mtpContextPtr_ is nullptr");
130 handleptr_ = make_shared<MtpOperationUtils>(mtpContextPtr_);
131 CHECK_AND_RETURN_LOG(handleptr_ != nullptr, "SendStoreRemoved handleptr_ is nullptr");
132
133 uint32_t storageId{0};
134 CHECK_AND_RETURN_LOG(handleptr_->TryRemoveExternalStorage(fsUuid, storageId), "TryRemoveExternalStorage fail");
135 MEDIA_INFO_LOG("SendStoreRemoved storageId[%{public}d]", storageId);
136 mtpContextPtr_->storageInfoID = storageId;
137 SendEvent(MTP_EVENT_STORE_REMOVED_CODE);
138 }
139
SendEvent(const int32_t & code)140 void MtpEvent::SendEvent(const int32_t &code)
141 {
142 CHECK_AND_RETURN_LOG(mtpContextPtr_ != nullptr, "SendEvent failed, mtpContextPtr_ is nullptr");
143
144 shared_ptr<PayloadData> eventPayloadData;
145
146 uint16_t responseCode = EventPayloadData(code, eventPayloadData);
147 if (responseCode == MTP_UNDEFINED_CODE) {
148 MEDIA_DEBUG_LOG("Mtp Event GetPayloadData Error");
149 }
150 shared_ptr<HeaderData> eventHeaderData =
151 make_shared<HeaderData>(EVENT_CONTAINER_TYPE, code, HeaderData::sTransactionID_);
152 shared_ptr<MtpPacket> eventPacketPtr = std::make_shared<MtpPacket>(mtpContextPtr_, mtpContextPtr_->mtpDriver);
153 CHECK_AND_RETURN_LOG(eventPacketPtr != nullptr, "SendEvent failed, eventPacketPtr is nullptr");
154
155 eventPacketPtr->Init(eventHeaderData, eventPayloadData);
156 int errorCode = eventPacketPtr->Maker(true);
157 CHECK_AND_RETURN_LOG(errorCode == MTP_SUCCESS, "MtpEvent::SendEvent responsePacket Maker err: %{public}d",
158 errorCode);
159 int32_t result = 0;
160 auto startTime = std::chrono::high_resolution_clock::now();
161 errorCode = eventPacketPtr->Write(result);
162 auto endTime = std::chrono::high_resolution_clock::now();
163 std::chrono::duration<uint16_t, std::milli> duration =
164 std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);
165 MtpDfxReporter::GetInstance().DoSendResponseResultDfxReporter(mtpContextPtr_->operationCode, result,
166 duration.count(), OperateMode::writemode);
167 CHECK_AND_RETURN_LOG(errorCode == MTP_SUCCESS, "MtpEvent::SendEvent responsePacket Write err: %{public}d",
168 errorCode);
169 }
170
EventPayloadData(const uint16_t code,shared_ptr<PayloadData> & data)171 uint16_t MtpEvent::EventPayloadData(const uint16_t code, shared_ptr<PayloadData> &data)
172 {
173 uint16_t responseCode = MTP_UNDEFINED_CODE;
174 CHECK_AND_RETURN_RET_LOG(mtpContextPtr_ != nullptr,
175 responseCode, "EventPayloadData failed, mtpContextPtr_ is nullptr");
176
177 if (handleptr_ == nullptr) {
178 handleptr_ = make_shared<MtpOperationUtils>(mtpContextPtr_);
179 }
180 switch (code) {
181 case MTP_EVENT_OBJECT_ADDED_CODE:
182 case MTP_EVENT_OBJECT_REMOVED_CODE:
183 case MTP_EVENT_OBJECT_INFO_CHANGED_CODE:
184 responseCode = handleptr_->ObjectEvent(data, mtpContextPtr_->eventHandle);
185 break;
186 case MTP_EVENT_DEVICE_PROP_CHANGED_CODE:
187 responseCode = handleptr_->ObjectEvent(data, mtpContextPtr_->eventProperty);
188 break;
189 case MTP_EVENT_STORE_ADDED_CODE:
190 case MTP_EVENT_STORE_REMOVED_CODE:
191 responseCode = handleptr_->ObjectEvent(data, mtpContextPtr_->storageInfoID);
192 break;
193 default:
194 break;
195 }
196 return responseCode;
197 }
198 } // namespace Media
199 } // namespace OHOS