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 const int32_t zoneID = 0;
114 const bool isUpdatedAudioStrategy = false;
115 if (applyFocus == true && isAudioFocusApplied_ == false) {
116 result = audioPolicyServer_->ActivateAudioInterrupt(audioInterrupt, zoneID, isUpdatedAudioStrategy);
117 if (result == SUCCESS) {
118 isAudioFocusApplied_ = true;
119 audioPolicyServer_->CheckConnectedDevice();
120 } else {
121 AUDIO_WARNING_LOG("Activate audio interrupt failed, err = %{public}d", result);
122 }
123 } else if (applyFocus == false && isAudioFocusApplied_ == true) {
124 result = audioPolicyServer_->DeactivateAudioInterrupt(audioInterrupt, zoneID);
125 if (result == SUCCESS) {
126 isAudioFocusApplied_ = false;
127 thread switchThread(&AudioPolicyServer::SetDeviceConnectedFlagFalseAfterDuration, audioPolicyServer_);
128 switchThread.detach();
129 } else {
130 AUDIO_WARNING_LOG("Deactivate audio interrupt failed, err = %{public}d", result);
131 }
132 }
133 }
134
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)135 int32_t SyncHibernateListenerStub::OnRemoteRequest(uint32_t code, MessageParcel &data,
136 MessageParcel &reply, MessageOption &option)
137 {
138 AUDIO_DEBUG_LOG("code = %{public}d, flag = %{public}d", code, option.GetFlags());
139 std::u16string descriptor = SyncHibernateListenerStub::GetDescriptor();
140 std::u16string remoteDescriptor = data.ReadInterfaceToken();
141 CHECK_AND_RETURN_RET_LOG(descriptor == remoteDescriptor, -1, "Descriptor not match");
142
143 int32_t ret = ERR_OK;
144 switch (code) {
145 case static_cast<int32_t>(PowerMgr::SyncHibernateCallbackInterfaceCode::CMD_ON_SYNC_HIBERNATE):
146 ret = OnSyncHibernateCallbackStub();
147 break;
148 case static_cast<int32_t>(PowerMgr::SyncHibernateCallbackInterfaceCode::CMD_ON_SYNC_WAKEUP):
149 ret = OnSyncWakeupCallbackStub();
150 break;
151 default:
152 ret = IPCObjectStub::OnRemoteRequest(code, data, reply, option);
153 break;
154 }
155
156 return ret;
157 }
158
OnSyncHibernateCallbackStub()159 int32_t SyncHibernateListenerStub::OnSyncHibernateCallbackStub()
160 {
161 OnSyncHibernate();
162
163 return ERR_OK;
164 }
165
OnSyncWakeupCallbackStub()166 int32_t SyncHibernateListenerStub::OnSyncWakeupCallbackStub()
167 {
168 OnSyncWakeup();
169
170 return ERR_OK;
171 }
172
SyncHibernateListener(const sptr<AudioPolicyServer> audioPolicyServer)173 SyncHibernateListener::SyncHibernateListener(const sptr<AudioPolicyServer> audioPolicyServer)
174 : audioPolicyServer_(audioPolicyServer) {}
175
OnSyncHibernate()176 void SyncHibernateListener::OnSyncHibernate()
177 {
178 AUDIO_INFO_LOG("OnSyncHibernate in hibernate");
179 ControlAudioFocus(true);
180 CHECK_AND_RETURN_LOG(audioPolicyServer_, "audioPolicyServer_ is nullptr");
181 audioPolicyServer_->CheckHibernateState(true);
182 }
183
OnSyncWakeup(bool hibernateResult)184 void SyncHibernateListener::OnSyncWakeup(bool hibernateResult)
185 {
186 AUDIO_INFO_LOG("OnSyncWakeup in hibernate");
187 ControlAudioFocus(false);
188 CHECK_AND_RETURN_LOG(audioPolicyServer_, "audioPolicyServer_ is nullptr");
189 audioPolicyServer_->CheckHibernateState(false);
190 audioPolicyServer_->UpdateSafeVolumeByS4();
191 }
192
ControlAudioFocus(bool isHibernate)193 void SyncHibernateListener::ControlAudioFocus(bool isHibernate)
194 {
195 if (audioPolicyServer_ == nullptr) {
196 AUDIO_ERR_LOG("audioPolicyServer_ is nullptr");
197 return;
198 }
199
200 AudioInterrupt audioInterrupt;
201 PowerListerMethods::InitAudioInterruptInfo(audioInterrupt);
202
203 int32_t result = -1;
204 const int32_t zoneID = 0;
205 const bool isUpdatedAudioStrategy = false;
206 if (isHibernate) {
207 result = audioPolicyServer_->ActivateAudioInterrupt(audioInterrupt, zoneID, isUpdatedAudioStrategy);
208 if (result != SUCCESS) {
209 AUDIO_WARNING_LOG("Sync hibernate activate audio interrupt failed, err = %{public}d", result);
210 }
211 audioPolicyServer_->CheckConnectedDevice();
212 } else {
213 result = audioPolicyServer_->DeactivateAudioInterrupt(audioInterrupt, zoneID);
214 if (result != SUCCESS) {
215 AUDIO_WARNING_LOG("Sync hibernate deactivate audio interrupt failed, err = %{public}d", result);
216 }
217 thread switchThread(&AudioPolicyServer::SetDeviceConnectedFlagFalseAfterDuration, audioPolicyServer_);
218 switchThread.detach();
219 }
220 }
221 } // namespace AudioStandard
222 } // namespace OHOS
223