blob: 6c30a9e2cae1b156d92fe924f434936feee7cc4e [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" Sanghae47ae682019-06-05 16:52:47 +090016#ifndef FRAMEWORK_NATIVE_CMDS_IDLCLI_VIBRATOR_H_
17#define FRAMEWORK_NATIVE_CMDS_IDLCLI_VIBRATOR_H_
18
Harpreet \"Eli\" Sanghabbe78552020-04-09 17:16:40 +090019#include <future>
20
21#include <aidl/android/hardware/vibrator/BnVibratorCallback.h>
Harpreet \"Eli\" Sangha6ce6f732019-11-28 16:53:41 +090022#include <aidl/android/hardware/vibrator/IVibrator.h>
23#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
27#include "utils.h"
28
29#include "log/log.h"
30
31namespace android {
32
33using hardware::Return;
34
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\" Sangha6ce6f732019-11-28 16:53:41 +090050inline auto getService() {
Harpreet \"Eli\" Sanghacb350b82019-11-12 15:15:25 +090051 return I::getService();
52}
53
54template <>
Harpreet \"Eli\" Sangha6ce6f732019-11-28 16:53:41 +090055inline auto getService<aidl::android::hardware::vibrator::IVibrator>() {
56 const auto instance =
57 std::string() + aidl::android::hardware::vibrator::IVibrator::descriptor + "/default";
58 auto vibBinder = ndk::SpAIBinder(AServiceManager_getService(instance.c_str()));
59 return aidl::android::hardware::vibrator::IVibrator::fromBinder(vibBinder);
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +090060}
61
62template <typename I>
Harpreet \"Eli\" Sangha6ce6f732019-11-28 16:53:41 +090063using shared_ptr = std::result_of_t<decltype(getService<I>)&()>;
64
65template <typename I>
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +090066class HalWrapper {
67public:
68 static std::unique_ptr<HalWrapper> Create() {
69 // Assume that if getService returns a nullptr, HAL is not available on the
70 // device.
Harpreet \"Eli\" Sanghacb350b82019-11-12 15:15:25 +090071 auto hal = getService<I>();
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +090072 return hal ? std::unique_ptr<HalWrapper>(new HalWrapper(std::move(hal))) : nullptr;
73 }
74
75 template <class R, class... Args0, class... Args1>
Harpreet \"Eli\" Sanghacb350b82019-11-12 15:15:25 +090076 R call(R (I::*fn)(Args0...), Args1&&... args1) {
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +090077 return (*mHal.*fn)(std::forward<Args1>(args1)...);
78 }
79
80private:
Harpreet \"Eli\" Sangha6ce6f732019-11-28 16:53:41 +090081 HalWrapper(shared_ptr<I>&& hal) : mHal(std::move(hal)) {}
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +090082
83private:
Harpreet \"Eli\" Sangha6ce6f732019-11-28 16:53:41 +090084 shared_ptr<I> mHal;
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +090085};
86
87template <typename I>
88static auto getHal() {
89 static auto sHalWrapper = HalWrapper<I>::Create();
90 return sHalWrapper.get();
91}
92
93template <class R, class I, class... Args0, class... Args1>
Harpreet \"Eli\" Sanghacb350b82019-11-12 15:15:25 +090094R halCall(R (I::*fn)(Args0...), Args1&&... args1) {
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +090095 auto hal = getHal<I>();
96 return hal ? hal->call(fn, std::forward<Args1>(args1)...) : NullptrStatus<R>();
97}
98
99namespace idlcli {
100namespace vibrator {
101
102namespace V1_0 = ::android::hardware::vibrator::V1_0;
103namespace V1_1 = ::android::hardware::vibrator::V1_1;
104namespace V1_2 = ::android::hardware::vibrator::V1_2;
105namespace V1_3 = ::android::hardware::vibrator::V1_3;
Harpreet \"Eli\" Sangha6ce6f732019-11-28 16:53:41 +0900106namespace aidl = ::aidl::android::hardware::vibrator;
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +0900107
Harpreet \"Eli\" Sanghabbe78552020-04-09 17:16:40 +0900108class VibratorCallback : public aidl::BnVibratorCallback {
109public:
110 ndk::ScopedAStatus onComplete() override {
111 mPromise.set_value();
112 return ndk::ScopedAStatus::ok();
113 }
114 void waitForComplete() { mPromise.get_future().wait(); }
115
116private:
117 std::promise<void> mPromise;
118};
119
Harpreet "Eli" Sanghae47ae682019-06-05 16:52:47 +0900120} // namespace vibrator
121} // namespace idlcli
122
123} // namespace android
124
125#endif // FRAMEWORK_NATIVE_CMDS_IDLCLI_VIBRATOR_H_