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 #include "charging_sound.h"
16 
17 #include "battery_log.h"
18 #include "audio_haptic_sound.h"
19 #include "config_policy_utils.h"
20 #include "errors.h"
21 
22 namespace OHOS {
23 namespace PowerMgr {
24 const std::string CHARGER_SOUND_DEFAULT_PATH = "/vendor/etc/battery/PowerConnected.ogg";
25 const char* CHARGER_SOUND_RELATIVE_PATH = "resource/media/audio/ui/PowerConnected.ogg";
26 
27 class ChargingSoundCallBack : public Media::AudioHapticSoundCallback {
28 public:
ChargingSoundCallBack(std::shared_ptr<Media::AudioHapticSound> sound)29     explicit ChargingSoundCallBack(std::shared_ptr<Media::AudioHapticSound> sound) : sound_(sound) {}
30     virtual ~ChargingSoundCallBack() = default;
OnEndOfStream()31     void OnEndOfStream() override
32     {
33         if (sound_) {
34             sound_->ReleaseSound();
35         }
36     }
OnError(int32_t)37     void OnError(int32_t /* errorCode */) override
38     {
39         if (sound_) {
40             sound_->ReleaseSound();
41         }
42     }
OnFirstFrameWriting(uint64_t)43     void OnFirstFrameWriting(uint64_t /* latency */) override {}
OnInterrupt(const AudioStandard::InterruptEvent &)44     void OnInterrupt(const AudioStandard::InterruptEvent& /* interruptEvent */) override
45     {
46         if (sound_) {
47             sound_->ReleaseSound();
48         }
49     }
50 
51 private:
52     std::shared_ptr<Media::AudioHapticSound> sound_;
53 };
54 
GetInstance()55 ChargingSound& ChargingSound::GetInstance()
56 {
57     static ChargingSound instance;
58     return instance;
59 }
60 
GetPath(const char * uri) const61 std::string ChargingSound::GetPath(const char* uri) const
62 {
63     std::string ret {};
64     char buf[MAX_PATH_LEN] = {0};
65     char* path = GetOneCfgFile(uri, buf, MAX_PATH_LEN);
66     if (path) {
67         ret = path;
68     }
69     return ret;
70 }
71 
ChargingSound()72 ChargingSound::ChargingSound()
73 {
74     uri_ = GetPath(CHARGER_SOUND_RELATIVE_PATH);
75     if (uri_.empty()) {
76         BATTERY_HILOGE(COMP_SVC, "get sound path failed, using fallback path");
77         uri_ = CHARGER_SOUND_DEFAULT_PATH;
78     }
79     sound_ = Media::AudioHapticSound::CreateAudioHapticSound(
80         Media::AUDIO_LATENCY_MODE_NORMAL, uri_, false, AudioStandard::STREAM_USAGE_SYSTEM);
81     callback_ = std::make_shared<ChargingSoundCallBack>(sound_);
82     sound_->SetAudioHapticSoundCallback(callback_);
83 }
84 
Prepare() const85 void ChargingSound::Prepare() const
86 {
87     if (!sound_) {
88         BATTERY_HILOGE(COMP_SVC, "sound_ not created");
89         return;
90     }
91     int32_t errcode = sound_->PrepareSound();
92     if (errcode != ERR_OK) {
93         BATTERY_HILOGE(COMP_SVC, "prepare error, code: %{public}d", errcode);
94     }
95 }
96 
Start() const97 void ChargingSound::Start() const
98 {
99     if (!sound_) {
100         BATTERY_HILOGE(COMP_SVC, "sound_ not created");
101         return;
102     }
103     Prepare();
104     int32_t errcode = sound_->StartSound();
105     if (errcode != ERR_OK) {
106         BATTERY_HILOGE(COMP_SVC, "start sound error, code: %{public}d", errcode);
107     }
108 }
109 
Stop() const110 void ChargingSound::Stop() const
111 {
112     if (!sound_) {
113         return;
114     }
115     (void)sound_->ReleaseSound();
116 }
117 } // namespace PowerMgr
118 } // namespace OHOS