1 /*
2 * Copyright (c) 2023-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 #ifndef LOG_TAG
16 #define LOG_TAG "PowerStateListener"
17 #endif
18
19 #include "power_state_listener.h"
20
21 #include "suspend/sync_sleep_callback_ipc_interface_code.h"
22 #include "hibernate/sync_hibernate_callback_ipc_interface_code.h"
23 #include "audio_policy_server.h"
24
25 namespace OHOS {
26 namespace AudioStandard {
27 using namespace std::chrono_literals;
28 const int32_t AUDIO_INTERRUPT_SESSION_ID = 10000;
29
InitAudioInterruptInfo(AudioInterrupt & audioInterrupt)30 void PowerListerMethods::InitAudioInterruptInfo(AudioInterrupt& audioInterrupt)
31 {
32 audioInterrupt.contentType = ContentType::CONTENT_TYPE_UNKNOWN;
33 audioInterrupt.streamUsage = StreamUsage::STREAM_USAGE_UNKNOWN;
34 audioInterrupt.audioFocusType.streamType = AudioStreamType::STREAM_INTERNAL_FORCE_STOP;
35 audioInterrupt.audioFocusType.sourceType = SOURCE_TYPE_INVALID;
36 audioInterrupt.audioFocusType.isPlay = true;
37 audioInterrupt.streamId = AUDIO_INTERRUPT_SESSION_ID;
38 audioInterrupt.pid = getpid();
39 }
40
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)41 int32_t PowerStateListenerStub::OnRemoteRequest(uint32_t code, MessageParcel &data,
42 MessageParcel &reply, MessageOption &option)
43 {
44 AUDIO_DEBUG_LOG("code = %{public}d, flag = %{public}d", code, option.GetFlags());
45 std::u16string descriptor = PowerStateListenerStub::GetDescriptor();
46 std::u16string remoteDescriptor = data.ReadInterfaceToken();
47 CHECK_AND_RETURN_RET_LOG(descriptor == remoteDescriptor, -1, "Descriptor not match");
48
49 int32_t ret = ERR_OK;
50 switch (code) {
51 case static_cast<int32_t>(PowerMgr::SyncSleepCallbackInterfaceCode::CMD_ON_SYNC_SLEEP):
52 ret = OnSyncSleepCallbackStub(data);
53 break;
54 case static_cast<int32_t>(PowerMgr::SyncSleepCallbackInterfaceCode::CMD_ON_SYNC_WAKEUP):
55 ret = OnSyncWakeupCallbackStub(data);
56 break;
57 default:
58 ret = IPCObjectStub::OnRemoteRequest(code, data, reply, option);
59 break;
60 }
61
62 return ret;
63 }
64
OnSyncSleepCallbackStub(MessageParcel & data)65 int32_t PowerStateListenerStub::OnSyncSleepCallbackStub(MessageParcel &data)
66 {
67 bool forceSleep = data.ReadBool();
68 OnSyncSleep(forceSleep);
69
70 return ERR_OK;
71 }
72
OnSyncWakeupCallbackStub(MessageParcel & data)73 int32_t PowerStateListenerStub::OnSyncWakeupCallbackStub(MessageParcel &data)
74 {
75 bool forceSleep = data.ReadBool();
76 OnSyncWakeup(forceSleep);
77
78 return ERR_OK;
79 }
80
PowerStateListener(const sptr<AudioPolicyServer> audioPolicyServer)81 PowerStateListener::PowerStateListener(const sptr<AudioPolicyServer> audioPolicyServer)
82 : audioPolicyServer_(audioPolicyServer) {}
83
OnSyncSleep(bool OnForceSleep)84 void PowerStateListener::OnSyncSleep(bool OnForceSleep)
85 {
86 CHECK_AND_RETURN_LOG(OnForceSleep, "OnSyncSleep not force sleep");
87
88 AUDIO_INFO_LOG("OnSyncSleep, try to control audio focus");
89 ControlAudioFocus(true);
90 }
91
OnSyncWakeup(bool OnForceSleep)92 void PowerStateListener::OnSyncWakeup(bool OnForceSleep)
93 {
94 CHECK_AND_RETURN_LOG(OnForceSleep, "OnSyncWakeup not force sleep");
95
96 AUDIO_INFO_LOG("OnSyncWakeup, try to release audio focus");
97 ControlAudioFocus(false);
98 }
99
ControlAudioFocus(bool applyFocus)100 void PowerStateListener::ControlAudioFocus(bool applyFocus)
101 {
102 if (audioPolicyServer_ == nullptr) {
103 AUDIO_ERR_LOG("audioPolicyServer_ is nullptr");
104 return;
105 }
106 std::lock_guard<std::mutex> lock(focusMutex_);
107 AUDIO_INFO_LOG("control audio focus, want: %{public}d, last: %{public}d", applyFocus, isAudioFocusApplied_);
108
109 AudioInterrupt audioInterrupt;
110 PowerListerMethods::InitAudioInterruptInfo(audioInterrupt);
111
112 int32_t result = -1;
113 if (applyFocus == true && isAudioFocusApplied_ == false) {
114 result = audioPolicyServer_->ActivateAudioInterrupt(audioInterrupt);
115 if (result == SUCCESS) {
116 isAudioFocusApplied_ = true;
117 audioPolicyServer_->CheckConnectedDevice();
118 } else {
119 AUDIO_WARNING_LOG("Activate audio interrupt failed, err = %{public}d", result);
120 }
121 } else if (applyFocus == false && isAudioFocusApplied_ == true) {
122 result = audioPolicyServer_->DeactivateAudioInterrupt(audioInterrupt);
123 if (result == SUCCESS) {
124 isAudioFocusApplied_ = false;
125 thread switchThread(&AudioPolicyServer::SetDeviceConnectedFlagFalseAfterDuration, audioPolicyServer_);
126 switchThread.detach();
127 } else {
128 AUDIO_WARNING_LOG("Deactivate audio interrupt failed, err = %{public}d", result);
129 }
130 }
131 }
132
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)133 int32_t SyncHibernateListenerStub::OnRemoteRequest(uint32_t code, MessageParcel &data,
134 MessageParcel &reply, MessageOption &option)
135 {
136 AUDIO_DEBUG_LOG("code = %{public}d, flag = %{public}d", code, option.GetFlags());
137 std::u16string descriptor = SyncHibernateListenerStub::GetDescriptor();
138 std::u16string remoteDescriptor = data.ReadInterfaceToken();
139 CHECK_AND_RETURN_RET_LOG(descriptor == remoteDescriptor, -1, "Descriptor not match");
140
141 int32_t ret = ERR_OK;
142 switch (code) {
143 case static_cast<int32_t>(PowerMgr::SyncHibernateCallbackInterfaceCode::CMD_ON_SYNC_HIBERNATE):
144 ret = OnSyncHibernateCallbackStub();
145 break;
146 case static_cast<int32_t>(PowerMgr::SyncHibernateCallbackInterfaceCode::CMD_ON_SYNC_WAKEUP):
147 ret = OnSyncWakeupCallbackStub();
148 break;
149 default:
150 ret = IPCObjectStub::OnRemoteRequest(code, data, reply, option);
151 break;
152 }
153
154 return ret;
155 }
156
OnSyncHibernateCallbackStub()157 int32_t SyncHibernateListenerStub::OnSyncHibernateCallbackStub()
158 {
159 OnSyncHibernate();
160
161 return ERR_OK;
162 }
163
OnSyncWakeupCallbackStub()164 int32_t SyncHibernateListenerStub::OnSyncWakeupCallbackStub()
165 {
166 OnSyncWakeup();
167
168 return ERR_OK;
169 }
170
SyncHibernateListener(const sptr<AudioPolicyServer> audioPolicyServer)171 SyncHibernateListener::SyncHibernateListener(const sptr<AudioPolicyServer> audioPolicyServer)
172 : audioPolicyServer_(audioPolicyServer) {}
173
OnSyncHibernate()174 void SyncHibernateListener::OnSyncHibernate()
175 {
176 AUDIO_INFO_LOG("OnSyncHibernate in hibernate");
177 ControlAudioFocus(true);
178 CHECK_AND_RETURN_LOG(audioPolicyServer_, "audioPolicyServer_ is nullptr");
179 audioPolicyServer_->CheckHibernateState(true);
180 }
181
OnSyncWakeup(bool hibernateResult)182 void SyncHibernateListener::OnSyncWakeup(bool hibernateResult)
183 {
184 AUDIO_INFO_LOG("OnSyncWakeup in hibernate");
185 ControlAudioFocus(false);
186 CHECK_AND_RETURN_LOG(audioPolicyServer_, "audioPolicyServer_ is nullptr");
187 audioPolicyServer_->CheckHibernateState(false);
188 audioPolicyServer_->UpdateSafeVolumeByS4();
189 }
190
ControlAudioFocus(bool isHibernate)191 void SyncHibernateListener::ControlAudioFocus(bool isHibernate)
192 {
193 if (audioPolicyServer_ == nullptr) {
194 AUDIO_ERR_LOG("audioPolicyServer_ is nullptr");
195 return;
196 }
197
198 AudioInterrupt audioInterrupt;
199 PowerListerMethods::InitAudioInterruptInfo(audioInterrupt);
200
201 int32_t result = -1;
202 if (isHibernate) {
203 result = audioPolicyServer_->ActivateAudioInterrupt(audioInterrupt);
204 if (result != SUCCESS) {
205 AUDIO_WARNING_LOG("Sync hibernate activate audio interrupt failed, err = %{public}d", result);
206 }
207 audioPolicyServer_->CheckConnectedDevice();
208 } else {
209 result = audioPolicyServer_->DeactivateAudioInterrupt(audioInterrupt);
210 if (result != SUCCESS) {
211 AUDIO_WARNING_LOG("Sync hibernate deactivate audio interrupt failed, err = %{public}d", result);
212 }
213 thread switchThread(&AudioPolicyServer::SetDeviceConnectedFlagFalseAfterDuration, audioPolicyServer_);
214 switchThread.detach();
215 }
216 }
217 } // namespace AudioStandard
218 } // namespace OHOS
219