1 /*
2  * Copyright (C) 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 #define MLOG_TAG "MtpStoreObserver"
16 
17 #include "mtp_store_observer.h"
18 #include <thread>
19 #include "common_event_manager.h"
20 #include "common_event_support.h"
21 #include "media_log.h"
22 #include "mtp_event.h"
23 
24 namespace OHOS {
25 namespace Media {
26 namespace {
27 const std::string KEY_FS_UUID                 = "fsUuid";
28 const std::string KEY_VOLUME_STATE            = "volumeState";
29 std::shared_ptr<MtpStoreObserver> observer_   = nullptr;
30 std::shared_ptr<MtpOperationContext> context_ = nullptr;
31 const std::vector<std::string> events_        = {
32     EventFwk::CommonEventSupport::COMMON_EVENT_VOLUME_MOUNTED,
33     EventFwk::CommonEventSupport::COMMON_EVENT_VOLUME_UNMOUNTED
34 };
35 // copy from foundation/filemanagement/storage_service/interfaces/innerkits/storage_manager/native/volume_core.h
36 enum MtpVolumeState : int {
37     UNMOUNTED = 0,
38     CHECKING,
39     MOUNTED,
40     EJECTING,
41     REMOVED,
42     BADREMOVABLE
43 };
44 } // namespace
45 
MtpStoreObserver(const EventFwk::CommonEventSubscribeInfo & subscriberInfo)46 MtpStoreObserver::MtpStoreObserver(const EventFwk::CommonEventSubscribeInfo &subscriberInfo)
47     : EventFwk::CommonEventSubscriber(subscriberInfo)
48 {
49 }
50 
StartObserver()51 bool MtpStoreObserver::StartObserver()
52 {
53     MEDIA_INFO_LOG("MtpStoreObserver StartObserver");
54     CHECK_AND_RETURN_RET_LOG(observer_ == nullptr, false, "observer_ is registered");
55 
56     EventFwk::MatchingSkills matchingSkills;
57     for (const auto &event : events_) {
58         matchingSkills.AddEvent(event);
59     }
60 
61     EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
62     observer_ = std::make_shared<MtpStoreObserver>(subscribeInfo);
63     CHECK_AND_RETURN_RET_LOG(observer_ != nullptr, false, "observer_ is nullptr");
64 
65     bool ret = EventFwk::CommonEventManager::SubscribeCommonEvent(observer_);
66     MEDIA_INFO_LOG("MtpStoreObserver StartObserver end, ret = %{public}d", ret);
67     return ret;
68 }
69 
StopObserver()70 bool MtpStoreObserver::StopObserver()
71 {
72     MEDIA_INFO_LOG("MtpStoreObserver StopObserver");
73     CHECK_AND_RETURN_RET_LOG(observer_ != nullptr, false, "observer_ is not registered");
74 
75     bool ret = EventFwk::CommonEventManager::UnSubscribeCommonEvent(observer_);
76     observer_ = nullptr;
77     context_ = nullptr;
78     MEDIA_INFO_LOG("MtpStoreObserver StopObserver end, ret = %{public}d", ret);
79     return ret;
80 }
81 
OnReceiveEvent(const EventFwk::CommonEventData & eventData)82 void MtpStoreObserver::OnReceiveEvent(const EventFwk::CommonEventData &eventData)
83 {
84     MEDIA_DEBUG_LOG("MtpStoreObserver OnReceiveEvent");
85     const AAFwk::Want &want = eventData.GetWant();
86     std::string action = want.GetAction();
87     MEDIA_INFO_LOG("MtpStoreObserver OnReceiveEvent action = %{public}s", action.c_str());
88 
89     std::string fsUuid = want.GetStringParam(KEY_FS_UUID);
90     int volumeState = want.GetIntParam(KEY_VOLUME_STATE, CHECKING);
91 
92     std::thread([&, fsUuid, volumeState] {
93         CHECK_AND_RETURN_LOG(!fsUuid.empty(), "SendThread: fsUuid is empty");
94         CHECK_AND_RETURN_LOG(context_ != nullptr, "SendThread: context_ is nullptr");
95 
96         std::shared_ptr<MtpEvent> eventPtr = std::make_shared<MtpEvent>(context_);
97         CHECK_AND_RETURN_LOG(eventPtr != nullptr, "SendThread: eventPtr is null");
98 
99         switch (volumeState) {
100             case MOUNTED:
101                 eventPtr->SendStoreAdded(fsUuid);
102                 break;
103             case UNMOUNTED:
104                 eventPtr->SendStoreRemoved(fsUuid);
105                 break;
106             default:
107                 MEDIA_ERR_LOG("SendThread: wrong state = [%{public}d]", volumeState);
108                 break;
109         }
110     }).detach();
111 }
112 
AttachContext(const std::shared_ptr<MtpOperationContext> & context)113 void MtpStoreObserver::AttachContext(const std::shared_ptr<MtpOperationContext> &context)
114 {
115     context_ = context;
116 }
117 
118 } // namespace Media
119 } // namespace OHOS
120