blob: b9434950f6a402a73a45fcdf8828da570a7a338e [file] [log] [blame]
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +09001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Harpreet Eli Sangha32226c92020-08-07 16:28:51 +090016#pragma once
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +090017
Harpreet \"Eli\" Sanghabbe78552020-04-09 17:16:40 +090018#include <future>
19
20#include <aidl/android/hardware/vibrator/BnVibratorCallback.h>
Harpreet \"Eli\" Sangha6ce6f732019-11-28 16:53:41 +090021#include <aidl/android/hardware/vibrator/IVibrator.h>
Harpreet Eli Sangha32226c92020-08-07 16:28:51 +090022#include <aidl/android/hardware/vibrator/IVibratorManager.h>
Harpreet \"Eli\" Sangha6ce6f732019-11-28 16:53:41 +090023#include <android/binder_manager.h>
Harpreet \"Eli\" Sanghabbe78552020-04-09 17:16:40 +090024#include <android/binder_process.h>
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +090025#include <android/hardware/vibrator/1.3/IVibrator.h>
26
Harpreet Eli Sangha32226c92020-08-07 16:28:51 +090027#include "IdlCli.h"
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +090028#include "utils.h"
29
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +090030namespace android {
31
32using hardware::Return;
Harpreet Eli Sangha32226c92020-08-07 16:28:51 +090033using idlcli::IdlCli;
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +090034
35static constexpr int NUM_TRIES = 2;
36
37// Creates a Return<R> with STATUS::EX_NULL_POINTER.
38template <class R>
Harpreet \"Eli\" Sanghacb350b82019-11-12 15:15:25 +090039inline R NullptrStatus() {
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +090040 using ::android::hardware::Status;
Harpreet \"Eli\" Sanghacb350b82019-11-12 15:15:25 +090041 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
42}
43
44template <>
Harpreet \"Eli\" Sangha6ce6f732019-11-28 16:53:41 +090045inline ndk::ScopedAStatus NullptrStatus() {
46 return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_NULL_POINTER));
Harpreet \"Eli\" Sanghacb350b82019-11-12 15:15:25 +090047}
48
49template <typename I>
Harpreet Eli Sangha32226c92020-08-07 16:28:51 +090050inline auto getService(std::string name) {
51 const auto instance = std::string() + I::descriptor + "/" + name;
Lais Andradef172ea12024-07-12 13:45:01 +010052 auto vibBinder = ndk::SpAIBinder(AServiceManager_checkService(instance.c_str()));
Harpreet Eli Sangha32226c92020-08-07 16:28:51 +090053 return I::fromBinder(vibBinder);
Harpreet \"Eli\" Sanghacb350b82019-11-12 15:15:25 +090054}
55
56template <>
Harpreet Eli Sangha32226c92020-08-07 16:28:51 +090057inline auto getService<android::hardware::vibrator::V1_0::IVibrator>(std::string name) {
58 return android::hardware::vibrator::V1_0::IVibrator::getService(name);
59}
60
61template <>
62inline auto getService<android::hardware::vibrator::V1_1::IVibrator>(std::string name) {
63 return android::hardware::vibrator::V1_1::IVibrator::getService(name);
64}
65
66template <>
67inline auto getService<android::hardware::vibrator::V1_2::IVibrator>(std::string name) {
68 return android::hardware::vibrator::V1_2::IVibrator::getService(name);
69}
70
71template <>
72inline auto getService<android::hardware::vibrator::V1_3::IVibrator>(std::string name) {
73 return android::hardware::vibrator::V1_3::IVibrator::getService(name);
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +090074}
75
76template <typename I>
Tomasz Wasilczyk2ed90a52024-01-09 15:44:58 -080077using shared_ptr = std::invoke_result_t<decltype(getService<I>)&, std::string>;
Harpreet \"Eli\" Sangha6ce6f732019-11-28 16:53:41 +090078
79template <typename I>
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +090080class HalWrapper {
81public:
82 static std::unique_ptr<HalWrapper> Create() {
83 // Assume that if getService returns a nullptr, HAL is not available on the
84 // device.
Harpreet Eli Sangha32226c92020-08-07 16:28:51 +090085 const auto name = IdlCli::Get().getName();
86 auto hal = getService<I>(name.empty() ? "default" : name);
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +090087 return hal ? std::unique_ptr<HalWrapper>(new HalWrapper(std::move(hal))) : nullptr;
88 }
89
90 template <class R, class... Args0, class... Args1>
Harpreet \"Eli\" Sanghacb350b82019-11-12 15:15:25 +090091 R call(R (I::*fn)(Args0...), Args1&&... args1) {
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +090092 return (*mHal.*fn)(std::forward<Args1>(args1)...);
93 }
94
95private:
Harpreet \"Eli\" Sangha6ce6f732019-11-28 16:53:41 +090096 HalWrapper(shared_ptr<I>&& hal) : mHal(std::move(hal)) {}
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +090097
98private:
Harpreet \"Eli\" Sangha6ce6f732019-11-28 16:53:41 +090099 shared_ptr<I> mHal;
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +0900100};
101
102template <typename I>
103static auto getHal() {
104 static auto sHalWrapper = HalWrapper<I>::Create();
105 return sHalWrapper.get();
106}
107
108template <class R, class I, class... Args0, class... Args1>
Harpreet \"Eli\" Sanghacb350b82019-11-12 15:15:25 +0900109R halCall(R (I::*fn)(Args0...), Args1&&... args1) {
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +0900110 auto hal = getHal<I>();
111 return hal ? hal->call(fn, std::forward<Args1>(args1)...) : NullptrStatus<R>();
112}
113
114namespace idlcli {
115namespace vibrator {
116
117namespace V1_0 = ::android::hardware::vibrator::V1_0;
118namespace V1_1 = ::android::hardware::vibrator::V1_1;
119namespace V1_2 = ::android::hardware::vibrator::V1_2;
120namespace V1_3 = ::android::hardware::vibrator::V1_3;
Harpreet \"Eli\" Sangha6ce6f732019-11-28 16:53:41 +0900121namespace aidl = ::aidl::android::hardware::vibrator;
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +0900122
Harpreet \"Eli\" Sanghabbe78552020-04-09 17:16:40 +0900123class VibratorCallback : public aidl::BnVibratorCallback {
124public:
125 ndk::ScopedAStatus onComplete() override {
126 mPromise.set_value();
127 return ndk::ScopedAStatus::ok();
128 }
129 void waitForComplete() { mPromise.get_future().wait(); }
130
131private:
132 std::promise<void> mPromise;
133};
134
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +0900135} // namespace vibrator
136} // namespace idlcli
137
138} // namespace android