• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project *
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 
16 #include <thread>
17 
18 #include "utils.h"
19 #include "vibrator.h"
20 
21 using std::chrono::milliseconds;
22 using std::this_thread::sleep_for;
23 
24 namespace android {
25 namespace idlcli {
26 
27 class CommandVibrator;
28 
29 namespace vibrator {
30 
31 using aidl::Effect;
32 using aidl::EffectStrength;
33 
34 class CommandPerform : public Command {
getDescription() const35     std::string getDescription() const override { return "Perform vibration effect."; }
36 
getUsageSummary() const37     std::string getUsageSummary() const override { return "[options] <effect> <strength>"; }
38 
getUsageDetails() const39     UsageDetails getUsageDetails() const override {
40         UsageDetails details{
41                 {"-b", {"Block for duration of vibration."}},
42                 {"<effect>", {"Effect ID."}},
43                 {"<strength>", {"0-2."}},
44         };
45         return details;
46     }
47 
doArgs(Args & args)48     Status doArgs(Args &args) override {
49         while (args.get<std::string>().value_or("").find("-") == 0) {
50             auto opt = *args.pop<std::string>();
51             if (opt == "--") {
52                 break;
53             } else if (opt == "-b") {
54                 mBlocking = true;
55             } else {
56                 std::cerr << "Invalid Option '" << opt << "'!" << std::endl;
57                 return USAGE;
58             }
59         }
60         if (auto effect = args.pop<decltype(mEffect)>()) {
61             mEffect = *effect;
62             std::cout << "Effect: " << toString(mEffect) << std::endl;
63         } else {
64             std::cerr << "Missing or Invalid Effect!" << std::endl;
65             return USAGE;
66         }
67         if (auto strength = args.pop<decltype(mStrength)>()) {
68             mStrength = *strength;
69             std::cout << "Strength: " << toString(mStrength) << std::endl;
70         } else {
71             std::cerr << "Missing or Invalid Strength!" << std::endl;
72             return USAGE;
73         }
74         if (!args.empty()) {
75             std::cerr << "Unexpected Arguments!" << std::endl;
76             return USAGE;
77         }
78         return OK;
79     }
80 
doMain(Args &&)81     Status doMain(Args && /*args*/) override {
82         auto hal = getHal();
83 
84         if (!hal) {
85             return UNAVAILABLE;
86         }
87 
88         uint32_t lengthMs;
89         std::shared_ptr<VibratorCallback> callback;
90 
91         ABinderProcess_setThreadPoolMaxThreadCount(1);
92         ABinderProcess_startThreadPool();
93 
94         int32_t cap;
95         hal->getCapabilities(&cap);
96 
97         if (mBlocking && (cap & aidl::IVibrator::CAP_PERFORM_CALLBACK)) {
98             callback = ndk::SharedRefBase::make<VibratorCallback>();
99         }
100 
101         int32_t aidlLengthMs;
102         auto status = hal->perform(mEffect, mStrength, callback, &aidlLengthMs);
103 
104         lengthMs = static_cast<uint32_t>(aidlLengthMs);
105 
106         if (status.isOk() && mBlocking) {
107             if (callback) {
108                 callback->waitForComplete();
109             } else {
110                 sleep_for(milliseconds(lengthMs));
111             }
112         }
113 
114         std::cout << "Status: " << status.getDescription() << std::endl;
115         std::cout << "Length: " << lengthMs << std::endl;
116 
117         return status.isOk() ? OK : ERROR;
118     }
119 
120     bool mBlocking;
121     Effect mEffect;
122     EffectStrength mStrength;
123 };
124 
125 static const auto Command = CommandRegistry<CommandVibrator>::Register<CommandPerform>("perform");
126 
127 } // namespace vibrator
128 } // namespace idlcli
129 } // namespace android
130