diff options
-rw-r--r-- | cmds/idlcli/Android.bp | 6 | ||||
-rw-r--r-- | cmds/idlcli/utils.h | 3 | ||||
-rw-r--r-- | cmds/idlcli/vibrator.h | 16 | ||||
-rw-r--r-- | cmds/idlcli/vibrator/CommandAlwaysOnDisable.cpp | 79 | ||||
-rw-r--r-- | cmds/idlcli/vibrator/CommandAlwaysOnEnable.cpp | 102 | ||||
-rw-r--r-- | cmds/idlcli/vibrator/CommandCompose.cpp | 51 | ||||
-rw-r--r-- | cmds/idlcli/vibrator/CommandGetPrimitiveDuration.cpp | 86 | ||||
-rw-r--r-- | cmds/idlcli/vibrator/CommandGetSupportedAlwaysOnEffects.cpp | 75 | ||||
-rw-r--r-- | cmds/idlcli/vibrator/CommandGetSupportedEffects.cpp | 74 | ||||
-rw-r--r-- | cmds/idlcli/vibrator/CommandGetSupportedPrimitives.cpp | 75 | ||||
-rw-r--r-- | cmds/idlcli/vibrator/CommandOn.cpp | 42 | ||||
-rw-r--r-- | cmds/idlcli/vibrator/CommandPerform.cpp | 64 | ||||
-rw-r--r-- | cmds/installd/dexopt.cpp | 11 | ||||
-rw-r--r-- | cmds/installd/dexopt.h | 6 | ||||
-rw-r--r-- | cmds/installd/tests/installd_dexopt_test.cpp | 30 | ||||
-rw-r--r-- | libs/binder/Android.bp | 1 | ||||
-rw-r--r-- | libs/binder/ndk/test/Android.bp | 2 | ||||
-rw-r--r-- | libs/binder/tests/Android.bp | 1 | ||||
-rw-r--r-- | libs/binderthreadstate/Android.bp | 1 |
19 files changed, 694 insertions, 31 deletions
diff --git a/cmds/idlcli/Android.bp b/cmds/idlcli/Android.bp index 402767a426..64bfdf9289 100644 --- a/cmds/idlcli/Android.bp +++ b/cmds/idlcli/Android.bp @@ -37,10 +37,16 @@ cc_library { defaults: ["idlcli-defaults"], srcs: [ "CommandVibrator.cpp", + "vibrator/CommandAlwaysOnDisable.cpp", + "vibrator/CommandAlwaysOnEnable.cpp", "vibrator/CommandCompose.cpp", "vibrator/CommandGetCapabilities.cpp", "vibrator/CommandGetCompositionDelayMax.cpp", "vibrator/CommandGetCompositionSizeMax.cpp", + "vibrator/CommandGetPrimitiveDuration.cpp", + "vibrator/CommandGetSupportedAlwaysOnEffects.cpp", + "vibrator/CommandGetSupportedEffects.cpp", + "vibrator/CommandGetSupportedPrimitives.cpp", "vibrator/CommandOff.cpp", "vibrator/CommandOn.cpp", "vibrator/CommandPerform.cpp", diff --git a/cmds/idlcli/utils.h b/cmds/idlcli/utils.h index a8e595470d..b8744555e2 100644 --- a/cmds/idlcli/utils.h +++ b/cmds/idlcli/utils.h @@ -17,6 +17,7 @@ #ifndef FRAMEWORK_NATIVE_CMDS_IDLCLI_UTILS_H_ #define FRAMEWORK_NATIVE_CMDS_IDLCLI_UTILS_H_ +#include <android/binder_enums.h> #include <hidl/HidlSupport.h> #include <iomanip> @@ -66,7 +67,7 @@ inline std::istream &operator>>(std::istream &stream, uint8_t &out) { } // namespace overrides -template <typename T, typename R = hardware::hidl_enum_range<T>> +template <typename T, typename R = ndk::enum_range<T>> inline std::istream &operator>>(std::istream &stream, T &out) { using overrides::operator>>; auto validRange = R(); diff --git a/cmds/idlcli/vibrator.h b/cmds/idlcli/vibrator.h index ca5142dee9..6c30a9e2ca 100644 --- a/cmds/idlcli/vibrator.h +++ b/cmds/idlcli/vibrator.h @@ -16,8 +16,12 @@ #ifndef FRAMEWORK_NATIVE_CMDS_IDLCLI_VIBRATOR_H_ #define FRAMEWORK_NATIVE_CMDS_IDLCLI_VIBRATOR_H_ +#include <future> + +#include <aidl/android/hardware/vibrator/BnVibratorCallback.h> #include <aidl/android/hardware/vibrator/IVibrator.h> #include <android/binder_manager.h> +#include <android/binder_process.h> #include <android/hardware/vibrator/1.3/IVibrator.h> #include "utils.h" @@ -101,6 +105,18 @@ namespace V1_2 = ::android::hardware::vibrator::V1_2; namespace V1_3 = ::android::hardware::vibrator::V1_3; namespace aidl = ::aidl::android::hardware::vibrator; +class VibratorCallback : public aidl::BnVibratorCallback { +public: + ndk::ScopedAStatus onComplete() override { + mPromise.set_value(); + return ndk::ScopedAStatus::ok(); + } + void waitForComplete() { mPromise.get_future().wait(); } + +private: + std::promise<void> mPromise; +}; + } // namespace vibrator } // namespace idlcli diff --git a/cmds/idlcli/vibrator/CommandAlwaysOnDisable.cpp b/cmds/idlcli/vibrator/CommandAlwaysOnDisable.cpp new file mode 100644 index 0000000000..9afa300c2b --- /dev/null +++ b/cmds/idlcli/vibrator/CommandAlwaysOnDisable.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2020 The Android Open Source Project * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "utils.h" +#include "vibrator.h" + +namespace android { +namespace idlcli { + +class CommandVibrator; + +namespace vibrator { + +class CommandAlwaysOnDisable : public Command { + std::string getDescription() const override { return "Disarm always-on haptic source."; } + + std::string getUsageSummary() const override { return "<id>"; } + + UsageDetails getUsageDetails() const override { + UsageDetails details{ + {"<id>", {"Source ID (device-specific)."}}, + }; + return details; + } + + Status doArgs(Args &args) override { + if (auto id = args.pop<decltype(mId)>()) { + mId = *id; + std::cout << "Source ID: " << mId << std::endl; + } else { + std::cerr << "Missing or Invalid Source ID!" << std::endl; + return USAGE; + } + if (!args.empty()) { + std::cerr << "Unexpected Arguments!" << std::endl; + return USAGE; + } + return OK; + } + + Status doMain(Args && /*args*/) override { + std::string statusStr; + Status ret; + + if (auto hal = getHal<aidl::IVibrator>()) { + auto status = hal->call(&aidl::IVibrator::alwaysOnDisable, mId); + + statusStr = status.getDescription(); + ret = status.isOk() ? OK : ERROR; + } else { + return UNAVAILABLE; + } + + std::cout << "Status: " << statusStr << std::endl; + + return ret; + } + + int32_t mId; +}; + +static const auto Command = + CommandRegistry<CommandVibrator>::Register<CommandAlwaysOnDisable>("alwaysOnDisable"); + +} // namespace vibrator +} // namespace idlcli +} // namespace android diff --git a/cmds/idlcli/vibrator/CommandAlwaysOnEnable.cpp b/cmds/idlcli/vibrator/CommandAlwaysOnEnable.cpp new file mode 100644 index 0000000000..bb7f9f284a --- /dev/null +++ b/cmds/idlcli/vibrator/CommandAlwaysOnEnable.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2020 The Android Open Source Project * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "utils.h" +#include "vibrator.h" + +namespace android { +namespace idlcli { + +class CommandVibrator; + +namespace vibrator { + +using aidl::Effect; +using aidl::EffectStrength; + +class CommandAlwaysOnEnable : public Command { + std::string getDescription() const override { + return "Arm always-on haptic source with an effect."; + } + + std::string getUsageSummary() const override { return "<id> <effect> <strength>"; } + + UsageDetails getUsageDetails() const override { + UsageDetails details{ + {"<id>", {"Source ID (device-specific)."}}, + {"<effect>", {"Effect ID."}}, + {"<strength>", {"0-2."}}, + }; + return details; + } + + Status doArgs(Args &args) override { + if (auto id = args.pop<decltype(mId)>()) { + mId = *id; + std::cout << "Source ID: " << mId << std::endl; + } else { + std::cerr << "Missing or Invalid Source ID!" << std::endl; + return USAGE; + } + if (auto effect = args.pop<decltype(mEffect)>()) { + mEffect = *effect; + std::cout << "Effect: " << toString(mEffect) << std::endl; + } else { + std::cerr << "Missing or Invalid Effect!" << std::endl; + return USAGE; + } + if (auto strength = args.pop<decltype(mStrength)>()) { + mStrength = *strength; + std::cout << "Strength: " << toString(mStrength) << std::endl; + } else { + std::cerr << "Missing or Invalid Strength!" << std::endl; + return USAGE; + } + if (!args.empty()) { + std::cerr << "Unexpected Arguments!" << std::endl; + return USAGE; + } + return OK; + } + + Status doMain(Args && /*args*/) override { + std::string statusStr; + Status ret; + + if (auto hal = getHal<aidl::IVibrator>()) { + auto status = hal->call(&aidl::IVibrator::alwaysOnEnable, mId, mEffect, mStrength); + + statusStr = status.getDescription(); + ret = status.isOk() ? OK : ERROR; + } else { + return UNAVAILABLE; + } + + std::cout << "Status: " << statusStr << std::endl; + + return ret; + } + + int32_t mId; + Effect mEffect; + EffectStrength mStrength; +}; + +static const auto Command = + CommandRegistry<CommandVibrator>::Register<CommandAlwaysOnEnable>("alwaysOnEnable"); + +} // namespace vibrator +} // namespace idlcli +} // namespace android diff --git a/cmds/idlcli/vibrator/CommandCompose.cpp b/cmds/idlcli/vibrator/CommandCompose.cpp index 4721a5f9ae..97c057fa0c 100644 --- a/cmds/idlcli/vibrator/CommandCompose.cpp +++ b/cmds/idlcli/vibrator/CommandCompose.cpp @@ -28,10 +28,13 @@ using aidl::CompositeEffect; class CommandCompose : public Command { std::string getDescription() const override { return "Compose vibration."; } - std::string getUsageSummary() const override { return "<delay> <primitive> <scale> ..."; } + std::string getUsageSummary() const override { + return "[options] <delay> <primitive> <scale> ..."; + } UsageDetails getUsageDetails() const override { UsageDetails details{ + {"-b", {"Block for duration of vibration."}}, {"<delay>", {"In milliseconds"}}, {"<primitive>", {"Primitive ID."}}, {"<scale>", {"0.0 (exclusive) - 1.0 (inclusive)."}}, @@ -41,6 +44,17 @@ class CommandCompose : public Command { } Status doArgs(Args &args) override { + while (args.get<std::string>().value_or("").find("-") == 0) { + auto opt = *args.pop<std::string>(); + if (opt == "--") { + break; + } else if (opt == "-b") { + mBlocking = true; + } else { + std::cerr << "Invalid Option '" << opt << "'!" << std::endl; + return USAGE; + } + } while (!args.empty()) { CompositeEffect effect; if (auto delay = args.pop<decltype(effect.delayMs)>()) { @@ -50,9 +64,8 @@ class CommandCompose : public Command { std::cerr << "Missing or Invalid Delay!" << std::endl; return USAGE; } - // TODO: Use range validation when supported by AIDL - if (auto primitive = args.pop<std::underlying_type_t<decltype(effect.primitive)>>()) { - effect.primitive = static_cast<decltype(effect.primitive)>(*primitive); + if (auto primitive = args.pop<decltype(effect.primitive)>()) { + effect.primitive = *primitive; std::cout << "Primitive: " << toString(effect.primitive) << std::endl; } else { std::cerr << "Missing or Invalid Primitive!" << std::endl; @@ -76,21 +89,33 @@ class CommandCompose : public Command { } Status doMain(Args && /*args*/) override { - std::string statusStr; - Status ret; - if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::compose, mComposite, nullptr); - statusStr = status.getDescription(); - ret = status.isOk() ? OK : ERROR; - } else { + auto hal = getHal<aidl::IVibrator>(); + + if (!hal) { return UNAVAILABLE; } - std::cout << "Status: " << statusStr << std::endl; + ABinderProcess_setThreadPoolMaxThreadCount(1); + ABinderProcess_startThreadPool(); + + std::shared_ptr<VibratorCallback> callback; + + if (mBlocking) { + callback = ndk::SharedRefBase::make<VibratorCallback>(); + } + + auto status = hal->call(&aidl::IVibrator::compose, mComposite, callback); + + if (status.isOk() && callback) { + callback->waitForComplete(); + } + + std::cout << "Status: " << status.getDescription() << std::endl; - return ret; + return status.isOk() ? OK : ERROR; } + bool mBlocking; std::vector<CompositeEffect> mComposite; }; diff --git a/cmds/idlcli/vibrator/CommandGetPrimitiveDuration.cpp b/cmds/idlcli/vibrator/CommandGetPrimitiveDuration.cpp new file mode 100644 index 0000000000..460d39e64f --- /dev/null +++ b/cmds/idlcli/vibrator/CommandGetPrimitiveDuration.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2020 The Android Open Source Project * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <future> + +#include "utils.h" +#include "vibrator.h" + +namespace android { +namespace idlcli { + +class CommandVibrator; + +namespace vibrator { + +using aidl::CompositePrimitive; + +class CommandGetPrimitiveDuration : public Command { + std::string getDescription() const override { + return "Retrieve effect primitive's duration in milliseconds."; + } + + std::string getUsageSummary() const override { return "<primitive>"; } + + UsageDetails getUsageDetails() const override { + UsageDetails details{ + {"<primitive>", {"Primitive ID."}}, + }; + return details; + } + + Status doArgs(Args &args) override { + if (auto primitive = args.pop<decltype(mPrimitive)>()) { + mPrimitive = *primitive; + std::cout << "Primitive: " << toString(mPrimitive) << std::endl; + } else { + std::cerr << "Missing or Invalid Primitive!" << std::endl; + return USAGE; + } + if (!args.empty()) { + std::cerr << "Unexpected Arguments!" << std::endl; + return USAGE; + } + return OK; + } + + Status doMain(Args && /*args*/) override { + std::string statusStr; + int32_t duration; + Status ret; + + if (auto hal = getHal<aidl::IVibrator>()) { + auto status = hal->call(&aidl::IVibrator::getPrimitiveDuration, mPrimitive, &duration); + statusStr = status.getDescription(); + ret = status.isOk() ? OK : ERROR; + } else { + return UNAVAILABLE; + } + + std::cout << "Status: " << statusStr << std::endl; + std::cout << "Duration: " << duration << std::endl; + + return ret; + } + + CompositePrimitive mPrimitive; +}; + +static const auto Command = CommandRegistry<CommandVibrator>::Register<CommandGetPrimitiveDuration>( + "getPrimitiveDuration"); + +} // namespace vibrator +} // namespace idlcli +} // namespace android diff --git a/cmds/idlcli/vibrator/CommandGetSupportedAlwaysOnEffects.cpp b/cmds/idlcli/vibrator/CommandGetSupportedAlwaysOnEffects.cpp new file mode 100644 index 0000000000..edfcd9195a --- /dev/null +++ b/cmds/idlcli/vibrator/CommandGetSupportedAlwaysOnEffects.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2020 The Android Open Source Project * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "utils.h" +#include "vibrator.h" + +namespace android { +namespace idlcli { + +class CommandVibrator; + +namespace vibrator { + +using aidl::Effect; + +class CommandGetSupportedAlwaysOnEffects : public Command { + std::string getDescription() const override { return "List of supported always-on effects."; } + + std::string getUsageSummary() const override { return ""; } + + UsageDetails getUsageDetails() const override { + UsageDetails details{}; + return details; + } + + Status doArgs(Args &args) override { + if (!args.empty()) { + std::cerr << "Unexpected Arguments!" << std::endl; + return USAGE; + } + return OK; + } + + Status doMain(Args && /*args*/) override { + std::string statusStr; + std::vector<Effect> effects; + Status ret; + + if (auto hal = getHal<aidl::IVibrator>()) { + auto status = hal->call(&aidl::IVibrator::getSupportedAlwaysOnEffects, &effects); + statusStr = status.getDescription(); + ret = status.isOk() ? OK : ERROR; + } else { + return UNAVAILABLE; + } + + std::cout << "Status: " << statusStr << std::endl; + std::cout << "Effects:" << std::endl; + for (auto &e : effects) { + std::cout << " " << toString(e) << std::endl; + } + + return ret; + } +}; + +static const auto Command = + CommandRegistry<CommandVibrator>::Register<CommandGetSupportedAlwaysOnEffects>( + "getSupportedAlwaysOnEffects"); + +} // namespace vibrator +} // namespace idlcli +} // namespace android diff --git a/cmds/idlcli/vibrator/CommandGetSupportedEffects.cpp b/cmds/idlcli/vibrator/CommandGetSupportedEffects.cpp new file mode 100644 index 0000000000..7658f22def --- /dev/null +++ b/cmds/idlcli/vibrator/CommandGetSupportedEffects.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2020 The Android Open Source Project * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "utils.h" +#include "vibrator.h" + +namespace android { +namespace idlcli { + +class CommandVibrator; + +namespace vibrator { + +using aidl::Effect; + +class CommandGetSupportedEffects : public Command { + std::string getDescription() const override { return "List supported effects."; } + + std::string getUsageSummary() const override { return ""; } + + UsageDetails getUsageDetails() const override { + UsageDetails details{}; + return details; + } + + Status doArgs(Args &args) override { + if (!args.empty()) { + std::cerr << "Unexpected Arguments!" << std::endl; + return USAGE; + } + return OK; + } + + Status doMain(Args && /*args*/) override { + std::string statusStr; + std::vector<Effect> effects; + Status ret; + + if (auto hal = getHal<aidl::IVibrator>()) { + auto status = hal->call(&aidl::IVibrator::getSupportedEffects, &effects); + statusStr = status.getDescription(); + ret = status.isOk() ? OK : ERROR; + } else { + return UNAVAILABLE; + } + + std::cout << "Status: " << statusStr << std::endl; + std::cout << "Effects:" << std::endl; + for (auto &e : effects) { + std::cout << " " << toString(e) << std::endl; + } + + return ret; + } +}; + +static const auto Command = CommandRegistry<CommandVibrator>::Register<CommandGetSupportedEffects>( + "getSupportedEffects"); + +} // namespace vibrator +} // namespace idlcli +} // namespace android diff --git a/cmds/idlcli/vibrator/CommandGetSupportedPrimitives.cpp b/cmds/idlcli/vibrator/CommandGetSupportedPrimitives.cpp new file mode 100644 index 0000000000..d101681914 --- /dev/null +++ b/cmds/idlcli/vibrator/CommandGetSupportedPrimitives.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2020 The Android Open Source Project * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "utils.h" +#include "vibrator.h" + +namespace android { +namespace idlcli { + +class CommandVibrator; + +namespace vibrator { + +using aidl::CompositePrimitive; + +class CommandGetSupportedPrimitives : public Command { + std::string getDescription() const override { return "List of supported effect primitive."; } + + std::string getUsageSummary() const override { return ""; } + + UsageDetails getUsageDetails() const override { + UsageDetails details{}; + return details; + } + + Status doArgs(Args &args) override { + if (!args.empty()) { + std::cerr << "Unexpected Arguments!" << std::endl; + return USAGE; + } + return OK; + } + + Status doMain(Args && /*args*/) override { + std::string statusStr; + std::vector<CompositePrimitive> primitives; + Status ret; + + if (auto hal = getHal<aidl::IVibrator>()) { + auto status = hal->call(&aidl::IVibrator::getSupportedPrimitives, &primitives); + statusStr = status.getDescription(); + ret = status.isOk() ? OK : ERROR; + } else { + return UNAVAILABLE; + } + + std::cout << "Status: " << statusStr << std::endl; + std::cout << "Primitives:" << std::endl; + for (auto &e : primitives) { + std::cout << " " << toString(e) << std::endl; + } + + return ret; + } +}; + +static const auto Command = + CommandRegistry<CommandVibrator>::Register<CommandGetSupportedPrimitives>( + "getSupportedPrimitives"); + +} // namespace vibrator +} // namespace idlcli +} // namespace android diff --git a/cmds/idlcli/vibrator/CommandOn.cpp b/cmds/idlcli/vibrator/CommandOn.cpp index 4e7e493d6d..8212fc14a7 100644 --- a/cmds/idlcli/vibrator/CommandOn.cpp +++ b/cmds/idlcli/vibrator/CommandOn.cpp @@ -13,9 +13,14 @@ * limitations under the License. */ +#include <thread> + #include "utils.h" #include "vibrator.h" +using std::chrono::milliseconds; +using std::this_thread::sleep_for; + namespace android { namespace idlcli { @@ -26,16 +31,28 @@ namespace vibrator { class CommandOn : public Command { std::string getDescription() const override { return "Turn on vibrator."; } - std::string getUsageSummary() const override { return "<duration>"; } + std::string getUsageSummary() const override { return "[options] <duration>"; } UsageDetails getUsageDetails() const override { UsageDetails details{ + {"-b", {"Block for duration of vibration."}}, {"<duration>", {"In milliseconds."}}, }; return details; } Status doArgs(Args &args) override { + while (args.get<std::string>().value_or("").find("-") == 0) { + auto opt = *args.pop<std::string>(); + if (opt == "--") { + break; + } else if (opt == "-b") { + mBlocking = true; + } else { + std::cerr << "Invalid Option '" << opt << "'!" << std::endl; + return USAGE; + } + } if (auto duration = args.pop<decltype(mDuration)>()) { mDuration = *duration; } else { @@ -52,9 +69,21 @@ class CommandOn : public Command { Status doMain(Args && /*args*/) override { std::string statusStr; Status ret; + std::shared_ptr<VibratorCallback> callback; if (auto hal = getHal<aidl::IVibrator>()) { - auto status = hal->call(&aidl::IVibrator::on, mDuration, nullptr); + ABinderProcess_setThreadPoolMaxThreadCount(1); + ABinderProcess_startThreadPool(); + + int32_t cap; + hal->call(&aidl::IVibrator::getCapabilities, &cap); + + if (mBlocking && (cap & aidl::IVibrator::CAP_ON_CALLBACK)) { + callback = ndk::SharedRefBase::make<VibratorCallback>(); + } + + auto status = hal->call(&aidl::IVibrator::on, mDuration, callback); + statusStr = status.getDescription(); ret = status.isOk() ? OK : ERROR; } else if (auto hal = getHal<V1_0::IVibrator>()) { @@ -65,11 +94,20 @@ class CommandOn : public Command { return UNAVAILABLE; } + if (ret == OK && mBlocking) { + if (callback) { + callback->waitForComplete(); + } else { + sleep_for(milliseconds(mDuration)); + } + } + std::cout << "Status: " << statusStr << std::endl; return ret; } + bool mBlocking; uint32_t mDuration; }; diff --git a/cmds/idlcli/vibrator/CommandPerform.cpp b/cmds/idlcli/vibrator/CommandPerform.cpp index 69c7e37744..c897686cbe 100644 --- a/cmds/idlcli/vibrator/CommandPerform.cpp +++ b/cmds/idlcli/vibrator/CommandPerform.cpp @@ -13,9 +13,14 @@ * limitations under the License. */ +#include <thread> + #include "utils.h" #include "vibrator.h" +using std::chrono::milliseconds; +using std::this_thread::sleep_for; + namespace android { namespace idlcli { @@ -51,16 +56,17 @@ static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_15) == static_assert(static_cast<uint8_t>(V1_3::Effect::TEXTURE_TICK) == static_cast<uint8_t>(aidl::Effect::TEXTURE_TICK)); -using V1_0::EffectStrength; -using V1_3::Effect; +using aidl::Effect; +using aidl::EffectStrength; class CommandPerform : public Command { std::string getDescription() const override { return "Perform vibration effect."; } - std::string getUsageSummary() const override { return "<effect> <strength>"; } + std::string getUsageSummary() const override { return "[options] <effect> <strength>"; } UsageDetails getUsageDetails() const override { UsageDetails details{ + {"-b", {"Block for duration of vibration."}}, {"<effect>", {"Effect ID."}}, {"<strength>", {"0-2."}}, }; @@ -68,6 +74,17 @@ class CommandPerform : public Command { } Status doArgs(Args &args) override { + while (args.get<std::string>().value_or("").find("-") == 0) { + auto opt = *args.pop<std::string>(); + if (opt == "--") { + break; + } else if (opt == "-b") { + mBlocking = true; + } else { + std::cerr << "Invalid Option '" << opt << "'!" << std::endl; + return USAGE; + } + } if (auto effect = args.pop<decltype(mEffect)>()) { mEffect = *effect; std::cout << "Effect: " << toString(mEffect) << std::endl; @@ -93,12 +110,23 @@ class CommandPerform : public Command { std::string statusStr; uint32_t lengthMs; Status ret; + std::shared_ptr<VibratorCallback> callback; if (auto hal = getHal<aidl::IVibrator>()) { + ABinderProcess_setThreadPoolMaxThreadCount(1); + ABinderProcess_startThreadPool(); + + int32_t cap; + hal->call(&aidl::IVibrator::getCapabilities, &cap); + + if (mBlocking && (cap & aidl::IVibrator::CAP_PERFORM_CALLBACK)) { + callback = ndk::SharedRefBase::make<VibratorCallback>(); + } + int32_t aidlLengthMs; - auto status = - hal->call(&aidl::IVibrator::perform, static_cast<aidl::Effect>(mEffect), - static_cast<aidl::EffectStrength>(mStrength), nullptr, &aidlLengthMs); + auto status = hal->call(&aidl::IVibrator::perform, mEffect, mStrength, callback, + &aidlLengthMs); + statusStr = status.getDescription(); lengthMs = static_cast<uint32_t>(aidlLengthMs); ret = status.isOk() ? OK : ERROR; @@ -111,17 +139,20 @@ class CommandPerform : public Command { }; if (auto hal = getHal<V1_3::IVibrator>()) { - hidlRet = hal->call(&V1_3::IVibrator::perform_1_3, - static_cast<V1_3::Effect>(mEffect), mStrength, callback); + hidlRet = + hal->call(&V1_3::IVibrator::perform_1_3, static_cast<V1_3::Effect>(mEffect), + static_cast<V1_0::EffectStrength>(mStrength), callback); } else if (auto hal = getHal<V1_2::IVibrator>()) { - hidlRet = hal->call(&V1_2::IVibrator::perform_1_2, - static_cast<V1_2::Effect>(mEffect), mStrength, callback); + hidlRet = + hal->call(&V1_2::IVibrator::perform_1_2, static_cast<V1_2::Effect>(mEffect), + static_cast<V1_0::EffectStrength>(mStrength), callback); } else if (auto hal = getHal<V1_1::IVibrator>()) { hidlRet = hal->call(&V1_1::IVibrator::perform_1_1, - static_cast<V1_1::Effect_1_1>(mEffect), mStrength, callback); + static_cast<V1_1::Effect_1_1>(mEffect), + static_cast<V1_0::EffectStrength>(mStrength), callback); } else if (auto hal = getHal<V1_0::IVibrator>()) { hidlRet = hal->call(&V1_0::IVibrator::perform, static_cast<V1_0::Effect>(mEffect), - mStrength, callback); + static_cast<V1_0::EffectStrength>(mStrength), callback); } else { return UNAVAILABLE; } @@ -130,12 +161,21 @@ class CommandPerform : public Command { ret = hidlRet.isOk() && status == V1_0::Status::OK ? OK : ERROR; } + if (ret == OK && mBlocking) { + if (callback) { + callback->waitForComplete(); + } else { + sleep_for(milliseconds(lengthMs)); + } + } + std::cout << "Status: " << statusStr << std::endl; std::cout << "Length: " << lengthMs << std::endl; return ret; } + bool mBlocking; Effect mEffect; EffectStrength mStrength; }; diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp index 9566cf66f6..3c0443595e 100644 --- a/cmds/installd/dexopt.cpp +++ b/cmds/installd/dexopt.cpp @@ -429,8 +429,17 @@ class RunDex2Oat : public ExecVHelper { MapPropertyToArg("dalvik.vm.dex2oat-very-large", "--very-large-app-threshold=%s"); + + // Decide whether to use dex2oat64. + bool use_dex2oat64 = false; + // Check whether the device even supports 64-bit ABIs. + if (!GetProperty("ro.product.cpu.abilist64", "").empty()) { + use_dex2oat64 = GetBoolProperty("dalvik.vm.dex2oat64.enabled", false); + } const char* dex2oat_bin = select_execution_binary( - kDex2oatPath, kDex2oatDebugPath, background_job_compile); + (use_dex2oat64 ? kDex2oat64Path : kDex2oat32Path), + (use_dex2oat64 ? kDex2oatDebug64Path : kDex2oatDebug32Path), + background_job_compile); bool generate_minidebug_info = kEnableMinidebugInfo && GetBoolProperty(kMinidebugInfoSystemProperty, kMinidebugInfoSystemPropertyDefault); diff --git a/cmds/installd/dexopt.h b/cmds/installd/dexopt.h index 92b13c79c1..d35953c058 100644 --- a/cmds/installd/dexopt.h +++ b/cmds/installd/dexopt.h @@ -36,8 +36,10 @@ static constexpr int DEX2OAT_FOR_FILTER = 3; #define ANDROID_ART_APEX_BIN "/apex/com.android.art/bin" // Location of binaries in the Android Runtime APEX. -static constexpr const char* kDex2oatPath = ANDROID_ART_APEX_BIN "/dex2oat"; -static constexpr const char* kDex2oatDebugPath = ANDROID_ART_APEX_BIN "/dex2oatd"; +static constexpr const char* kDex2oat32Path = ANDROID_ART_APEX_BIN "/dex2oat32"; +static constexpr const char* kDex2oat64Path = ANDROID_ART_APEX_BIN "/dex2oat64"; +static constexpr const char* kDex2oatDebug32Path = ANDROID_ART_APEX_BIN "/dex2oatd32"; +static constexpr const char* kDex2oatDebug64Path = ANDROID_ART_APEX_BIN "/dex2oatd64"; static constexpr const char* kProfmanPath = ANDROID_ART_APEX_BIN "/profman"; static constexpr const char* kProfmanDebugPath = ANDROID_ART_APEX_BIN "/profmand"; static constexpr const char* kDexoptanalyzerPath = ANDROID_ART_APEX_BIN "/dexoptanalyzer"; diff --git a/cmds/installd/tests/installd_dexopt_test.cpp b/cmds/installd/tests/installd_dexopt_test.cpp index 9a1888cf70..96f5e44030 100644 --- a/cmds/installd/tests/installd_dexopt_test.cpp +++ b/cmds/installd/tests/installd_dexopt_test.cpp @@ -749,6 +749,36 @@ TEST_F(DexoptTest, ResolveStartupConstStrings) { EXPECT_TRUE(found_enable); } +TEST_F(DexoptTest, DexoptDex2oat64Enabled) { + LOG(INFO) << "DexoptDex2oat64Enabled"; + const std::string property = "dalvik.vm.dex2oat64.enabled"; + const std::string previous_value = android::base::GetProperty(property, ""); + auto restore_property = android::base::make_scope_guard([=]() { + android::base::SetProperty(property, previous_value); + }); + std::string odex = GetPrimaryDexArtifact(app_oat_dir_.c_str(), apk_path_, "odex"); + // Disable the property and use dex2oat32. + ASSERT_TRUE(android::base::SetProperty(property, "false")) << property; + CompilePrimaryDexOk("speed-profile", + DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PROFILE_GUIDED | + DEXOPT_GENERATE_APP_IMAGE, + app_oat_dir_.c_str(), + kTestAppGid, + DEX2OAT_FROM_SCRATCH, + /*binder_result=*/nullptr, + empty_dm_file_.c_str()); + // Enable the property and use dex2oat64. + ASSERT_TRUE(android::base::SetProperty(property, "true")) << property; + CompilePrimaryDexOk("speed-profile", + DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PROFILE_GUIDED | + DEXOPT_GENERATE_APP_IMAGE, + app_oat_dir_.c_str(), + kTestAppGid, + DEX2OAT_FROM_SCRATCH, + /*binder_result=*/nullptr, + empty_dm_file_.c_str()); +} + class PrimaryDexReCompilationTest : public DexoptTest { public: virtual void SetUp() { diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp index e6cfeb4943..72982824f4 100644 --- a/libs/binder/Android.bp +++ b/libs/binder/Android.bp @@ -170,6 +170,7 @@ filegroup { aidl_interface { name: "libbinder_aidl_test_stub", + unstable: true, local_include_dir: "aidl", srcs: [":libbinder_aidl"], vendor_available: true, diff --git a/libs/binder/ndk/test/Android.bp b/libs/binder/ndk/test/Android.bp index cb4b20ff9d..5f5265c90e 100644 --- a/libs/binder/ndk/test/Android.bp +++ b/libs/binder/ndk/test/Android.bp @@ -92,6 +92,7 @@ cc_test { aidl_interface { name: "IBinderVendorDoubleLoadTest", + unstable: true, vendor: true, srcs: [ "IBinderVendorDoubleLoadTest.aidl", @@ -100,6 +101,7 @@ aidl_interface { aidl_interface { name: "IBinderNdkUnitTest", + unstable: true, srcs: [ "IBinderNdkUnitTest.aidl", "IEmpty.aidl", diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp index c7b75515cd..69fdd7c5d8 100644 --- a/libs/binder/tests/Android.bp +++ b/libs/binder/tests/Android.bp @@ -137,6 +137,7 @@ cc_test { aidl_interface { name: "binderStabilityTestIface", + unstable: true, srcs: [ "IBinderStabilityTest.aidl", ], diff --git a/libs/binderthreadstate/Android.bp b/libs/binderthreadstate/Android.bp index c1861104d3..5eb509c4a0 100644 --- a/libs/binderthreadstate/Android.bp +++ b/libs/binderthreadstate/Android.bp @@ -39,6 +39,7 @@ hidl_package_root { aidl_interface { name: "binderthreadstateutilstest.aidl", + unstable: true, srcs: ["IAidlStuff.aidl"], } |