1 /*
2  * Copyright (c) 2022-2023 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 
16 #ifndef OHOS_DAUDIO_SINK_DEV_H
17 #define OHOS_DAUDIO_SINK_DEV_H
18 
19 #include <atomic>
20 #include <condition_variable>
21 #include <mutex>
22 #include <initializer_list>
23 #include "cJSON.h"
24 
25 #include "event_handler.h"
26 
27 #include "daudio_sink_dev_ctrl_mgr.h"
28 #include "dmic_client.h"
29 #include "dspeaker_client.h"
30 #include "iaudio_event_callback.h"
31 #include "imic_client.h"
32 #include "ispk_client.h"
33 #include "i_av_engine_provider.h"
34 #include "i_av_receiver_engine_callback.h"
35 #include "idaudio_sink_ipc_callback.h"
36 
37 namespace OHOS {
38 namespace DistributedHardware {
39 enum class ChannelState {
40     SPK_CONTROL_OPENED,
41     MIC_CONTROL_OPENED,
42     UNKNOWN,
43 };
44 
45 class DAudioSinkDev : public IAudioEventCallback, public std::enable_shared_from_this<DAudioSinkDev> {
46 public:
47     explicit DAudioSinkDev(const std::string &networkId, const sptr<IDAudioSinkIpcCallback> &sinkCallback);
48     ~DAudioSinkDev() override;
49 
50     int32_t AwakeAudioDev();
51     void SleepAudioDev();
52     void NotifyEvent(const AudioEvent &audioEvent) override;
53     int32_t InitAVTransEngines(const ChannelState channelState, IAVEngineProvider *providerPtr);
54     int32_t PauseDistributedHardware(const std::string &networkId);
55     int32_t ResumeDistributedHardware(const std::string &networkId);
56     int32_t StopDistributedHardware(const std::string &networkId);
57     void JudgeDeviceStatus();
58     void SetDevLevelStatus(bool checkStatus);
59 
60 private:
61     int32_t TaskOpenDSpeaker(const std::string &args);
62     int32_t TaskCloseDSpeaker(const std::string &args);
63     int32_t TaskStartRender(const std::string &args);
64     int32_t TaskOpenDMic(const std::string &args);
65     int32_t TaskCloseDMic(const std::string &args);
66     int32_t TaskSetParameter(const std::string &args);
67     int32_t TaskVolumeChange(const std::string &args);
68     int32_t TaskFocusChange(const std::string &args);
69     int32_t TaskRenderStateChange(const std::string &args);
70     int32_t TaskSetVolume(const std::string &args);
71     int32_t TaskSetMute(const std::string &args);
72     int32_t TaskPlayStatusChange(const std::string &args);
73     int32_t TaskDisableDevice(const std::string &args);
74 
75     void NotifySourceDev(const AudioEventType type, const std::string dhId, const int32_t result);
76     int32_t from_json(const cJSON *j, AudioParam &audioParam);
77     int32_t HandleEngineMessage(uint32_t type, std::string content, std::string devId);
78     int32_t SendAudioEventToRemote(const AudioEvent &event);
79     void PullUpPage();
80 
81     int32_t GetParamValue(const cJSON *j, const char* key, int32_t &value);
82     int32_t GetCJsonObjectItems(const cJSON *j, AudioParam &audioParam);
83     int32_t ParseDhidFromEvent(std::string args);
84     int32_t ParseResultFromEvent(std::string args);
85     int32_t ConvertString2Int(std::string val);
86 
87 private:
88     std::mutex rpcWaitMutex_;
89     std::condition_variable rpcWaitCond_;
90     std::string devId_;
91     std::string spkDhId_;
92     std::string micDhId_;
93     std::mutex spkClientMutex_;
94     std::map<int32_t, std::shared_ptr<ISpkClient>> spkClientMap_;
95     std::mutex micClientMutex_;
96     std::map<int32_t, std::shared_ptr<DMicClient>> micClientMap_;
97     std::shared_ptr<DAudioSinkDevCtrlMgr> audioCtrlMgr_ = nullptr;
98     static constexpr size_t WAIT_HANDLER_IDLE_TIME_US = 10000;
99     const std::string SUBTYPE = "mic";
100     sptr<IDAudioSinkIpcCallback> ipcSinkCallback_ = nullptr;
101     std::atomic<bool> isPageStatus_ = false;
102 
103     std::atomic<bool> isSpkInUse_ = false;
104     std::atomic<bool> isMicInUse_ = false;
105     bool isDevLevelStatus_ = false;
106 
107     class SinkEventHandler : public AppExecFwk::EventHandler {
108     public:
109         SinkEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> &runner,
110             const std::shared_ptr<DAudioSinkDev> &dev);
111         ~SinkEventHandler() override;
112         void ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event) override;
113 
114     private:
115         void NotifyCtrlOpened(const AppExecFwk::InnerEvent::Pointer &event);
116         void NotifyCtrlClosed(const AppExecFwk::InnerEvent::Pointer &event);
117         void NotifyOpenSpeaker(const AppExecFwk::InnerEvent::Pointer &event);
118         void NotifyCloseSpeaker(const AppExecFwk::InnerEvent::Pointer &event);
119         void NotifySpeakerOpened(const AppExecFwk::InnerEvent::Pointer &event);
120         void NotifySpeakerClosed(const AppExecFwk::InnerEvent::Pointer &event);
121         void NotifyOpenMic(const AppExecFwk::InnerEvent::Pointer &event);
122         void NotifyCloseMic(const AppExecFwk::InnerEvent::Pointer &event);
123         void NotifyMicOpened(const AppExecFwk::InnerEvent::Pointer &event);
124         void NotifyMicClosed(const AppExecFwk::InnerEvent::Pointer &event);
125         void NotifySetVolume(const AppExecFwk::InnerEvent::Pointer &event);
126         void NotifyVolumeChange(const AppExecFwk::InnerEvent::Pointer &event);
127         void NotifySetParam(const AppExecFwk::InnerEvent::Pointer &event);
128         void NotifySetMute(const AppExecFwk::InnerEvent::Pointer &event);
129         void NotifyFocusChange(const AppExecFwk::InnerEvent::Pointer &event);
130         void NotifyRenderStateChange(const AppExecFwk::InnerEvent::Pointer &event);
131         void NotifyPlayStatusChange(const AppExecFwk::InnerEvent::Pointer &event);
132         int32_t GetEventParam(const AppExecFwk::InnerEvent::Pointer &event, std::string &eventParam);
133         void ProcessEventInner(const AppExecFwk::InnerEvent::Pointer &event);
134 
135     private:
136         using SinkEventFunc = void (SinkEventHandler::*)(const AppExecFwk::InnerEvent::Pointer &event);
137         std::map<uint32_t, SinkEventFunc> mapEventFuncs_;
138         std::weak_ptr<DAudioSinkDev> sinkDev_;
139     };
140     std::shared_ptr<SinkEventHandler> handler_;
141 };
142 } // DistributedHardware
143 } // OHOS
144 #endif // OHOS_DAUDIO_SINK_DEV_H
145