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