xref: /aosp_15_r20/hardware/interfaces/audio/aidl/vts/AudioHalBinderServiceUtil.h (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1*4d7e907cSAndroid Build Coastguard Worker /*
2*4d7e907cSAndroid Build Coastguard Worker  * Copyright (C) 2022 The Android Open Source Project
3*4d7e907cSAndroid Build Coastguard Worker  *
4*4d7e907cSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*4d7e907cSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*4d7e907cSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*4d7e907cSAndroid Build Coastguard Worker  *
8*4d7e907cSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*4d7e907cSAndroid Build Coastguard Worker  *
10*4d7e907cSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*4d7e907cSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*4d7e907cSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4d7e907cSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*4d7e907cSAndroid Build Coastguard Worker  * limitations under the License.
15*4d7e907cSAndroid Build Coastguard Worker  */
16*4d7e907cSAndroid Build Coastguard Worker 
17*4d7e907cSAndroid Build Coastguard Worker #pragma once
18*4d7e907cSAndroid Build Coastguard Worker 
19*4d7e907cSAndroid Build Coastguard Worker #include <condition_variable>
20*4d7e907cSAndroid Build Coastguard Worker #include <memory>
21*4d7e907cSAndroid Build Coastguard Worker #include <mutex>
22*4d7e907cSAndroid Build Coastguard Worker 
23*4d7e907cSAndroid Build Coastguard Worker #include <android-base/properties.h>
24*4d7e907cSAndroid Build Coastguard Worker #include <android/binder_auto_utils.h>
25*4d7e907cSAndroid Build Coastguard Worker #include <android/binder_manager.h>
26*4d7e907cSAndroid Build Coastguard Worker #include <android/binder_process.h>
27*4d7e907cSAndroid Build Coastguard Worker 
28*4d7e907cSAndroid Build Coastguard Worker #include <android-base/logging.h>
29*4d7e907cSAndroid Build Coastguard Worker 
30*4d7e907cSAndroid Build Coastguard Worker class AudioHalBinderServiceUtil {
31*4d7e907cSAndroid Build Coastguard Worker   public:
connectToService(const std::string & serviceName)32*4d7e907cSAndroid Build Coastguard Worker     ndk::SpAIBinder connectToService(const std::string& serviceName) {
33*4d7e907cSAndroid Build Coastguard Worker         mServiceName = serviceName;
34*4d7e907cSAndroid Build Coastguard Worker         mBinder = ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str()));
35*4d7e907cSAndroid Build Coastguard Worker         if (mBinder == nullptr) {
36*4d7e907cSAndroid Build Coastguard Worker             LOG(ERROR) << "Failed to get service " << serviceName;
37*4d7e907cSAndroid Build Coastguard Worker         } else {
38*4d7e907cSAndroid Build Coastguard Worker             LOG(DEBUG) << "Succeeded to get service " << serviceName;
39*4d7e907cSAndroid Build Coastguard Worker         }
40*4d7e907cSAndroid Build Coastguard Worker         return mBinder;
41*4d7e907cSAndroid Build Coastguard Worker     }
42*4d7e907cSAndroid Build Coastguard Worker 
43*4d7e907cSAndroid Build Coastguard Worker     ndk::SpAIBinder restartService(
44*4d7e907cSAndroid Build Coastguard Worker             std::chrono::milliseconds timeoutMs = std::chrono::milliseconds(3000)) {
45*4d7e907cSAndroid Build Coastguard Worker         if (!stopService(timeoutMs)) {
46*4d7e907cSAndroid Build Coastguard Worker             return {};
47*4d7e907cSAndroid Build Coastguard Worker         }
48*4d7e907cSAndroid Build Coastguard Worker         return connectToService(mServiceName);
49*4d7e907cSAndroid Build Coastguard Worker     }
50*4d7e907cSAndroid Build Coastguard Worker 
51*4d7e907cSAndroid Build Coastguard Worker   private:
52*4d7e907cSAndroid Build Coastguard Worker     class AidlDeathRecipient {
53*4d7e907cSAndroid Build Coastguard Worker       public:
AidlDeathRecipient(const ndk::SpAIBinder & binder)54*4d7e907cSAndroid Build Coastguard Worker         explicit AidlDeathRecipient(const ndk::SpAIBinder& binder)
55*4d7e907cSAndroid Build Coastguard Worker             : binder(binder), recipient(AIBinder_DeathRecipient_new(&binderDiedCallbackAidl)) {}
56*4d7e907cSAndroid Build Coastguard Worker 
linkToDeath()57*4d7e907cSAndroid Build Coastguard Worker         binder_status_t linkToDeath() {
58*4d7e907cSAndroid Build Coastguard Worker             return AIBinder_linkToDeath(binder.get(), recipient.get(), this);
59*4d7e907cSAndroid Build Coastguard Worker         }
60*4d7e907cSAndroid Build Coastguard Worker 
waitForFired(std::chrono::milliseconds timeoutMs)61*4d7e907cSAndroid Build Coastguard Worker         bool waitForFired(std::chrono::milliseconds timeoutMs) {
62*4d7e907cSAndroid Build Coastguard Worker             std::unique_lock<std::mutex> lock(mutex);
63*4d7e907cSAndroid Build Coastguard Worker             return condition.wait_for(lock, timeoutMs, [this]() { return fired; });
64*4d7e907cSAndroid Build Coastguard Worker         }
65*4d7e907cSAndroid Build Coastguard Worker 
66*4d7e907cSAndroid Build Coastguard Worker       private:
67*4d7e907cSAndroid Build Coastguard Worker         const ndk::SpAIBinder binder;
68*4d7e907cSAndroid Build Coastguard Worker         const ndk::ScopedAIBinder_DeathRecipient recipient;
69*4d7e907cSAndroid Build Coastguard Worker         std::mutex mutex;
70*4d7e907cSAndroid Build Coastguard Worker         std::condition_variable condition;
71*4d7e907cSAndroid Build Coastguard Worker         bool fired = false;
72*4d7e907cSAndroid Build Coastguard Worker 
binderDied()73*4d7e907cSAndroid Build Coastguard Worker         void binderDied() {
74*4d7e907cSAndroid Build Coastguard Worker             std::unique_lock<std::mutex> lock(mutex);
75*4d7e907cSAndroid Build Coastguard Worker             fired = true;
76*4d7e907cSAndroid Build Coastguard Worker             condition.notify_one();
77*4d7e907cSAndroid Build Coastguard Worker         };
78*4d7e907cSAndroid Build Coastguard Worker 
binderDiedCallbackAidl(void * cookie)79*4d7e907cSAndroid Build Coastguard Worker         static void binderDiedCallbackAidl(void* cookie) {
80*4d7e907cSAndroid Build Coastguard Worker             AidlDeathRecipient* self = static_cast<AidlDeathRecipient*>(cookie);
81*4d7e907cSAndroid Build Coastguard Worker             self->binderDied();
82*4d7e907cSAndroid Build Coastguard Worker         }
83*4d7e907cSAndroid Build Coastguard Worker     };
84*4d7e907cSAndroid Build Coastguard Worker 
stopService(std::chrono::milliseconds timeoutMs)85*4d7e907cSAndroid Build Coastguard Worker     bool stopService(std::chrono::milliseconds timeoutMs) {
86*4d7e907cSAndroid Build Coastguard Worker         AidlDeathRecipient deathHandler(mBinder);
87*4d7e907cSAndroid Build Coastguard Worker         if (STATUS_OK != deathHandler.linkToDeath()) {
88*4d7e907cSAndroid Build Coastguard Worker             LOG(ERROR) << "linkToDeath failed";
89*4d7e907cSAndroid Build Coastguard Worker             return false;
90*4d7e907cSAndroid Build Coastguard Worker         }
91*4d7e907cSAndroid Build Coastguard Worker         if (!android::base::SetProperty("sys.audio.restart.hal", "1")) {
92*4d7e907cSAndroid Build Coastguard Worker             LOG(ERROR) << "SetProperty failed";
93*4d7e907cSAndroid Build Coastguard Worker             return false;
94*4d7e907cSAndroid Build Coastguard Worker         }
95*4d7e907cSAndroid Build Coastguard Worker         if (!deathHandler.waitForFired(timeoutMs)) {
96*4d7e907cSAndroid Build Coastguard Worker             LOG(ERROR) << "Timeout wait for death of " << mServiceName;
97*4d7e907cSAndroid Build Coastguard Worker             return false;
98*4d7e907cSAndroid Build Coastguard Worker         }
99*4d7e907cSAndroid Build Coastguard Worker         return true;
100*4d7e907cSAndroid Build Coastguard Worker     }
101*4d7e907cSAndroid Build Coastguard Worker 
102*4d7e907cSAndroid Build Coastguard Worker     std::string mServiceName;
103*4d7e907cSAndroid Build Coastguard Worker     ndk::SpAIBinder mBinder;
104*4d7e907cSAndroid Build Coastguard Worker };
105