/* * Copyright (C) 2021 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 "ConnectedClient.h" #include "ParcelableUtils.h" #include #include #include #include #include namespace android { namespace hardware { namespace automotive { namespace vehicle { namespace { using ::aidl::android::hardware::automotive::vehicle::GetValueResult; using ::aidl::android::hardware::automotive::vehicle::GetValueResults; using ::aidl::android::hardware::automotive::vehicle::IVehicleCallback; using ::aidl::android::hardware::automotive::vehicle::SetValueResult; using ::aidl::android::hardware::automotive::vehicle::SetValueResults; using ::aidl::android::hardware::automotive::vehicle::StatusCode; using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue; using ::aidl::android::hardware::automotive::vehicle::VehiclePropValues; using ::android::base::Result; using ::ndk::ScopedAStatus; // A function to call the specific callback based on results type. template ScopedAStatus callCallback(std::shared_ptr callback, const T& results); template <> ScopedAStatus callCallback(std::shared_ptr callback, const GetValueResults& results) { return callback->onGetValues(results); } template <> ScopedAStatus callCallback(std::shared_ptr callback, const SetValueResults& results) { return callback->onSetValues(results); } // Send a single GetValue/SetValue result through the callback. template void sendGetOrSetValueResult(std::shared_ptr callback, const ResultType& result) { ResultsType parcelableResults; parcelableResults.payloads.resize(1); parcelableResults.payloads[0] = result; if (ScopedAStatus callbackStatus = callCallback(callback, parcelableResults); !callbackStatus.isOk()) { ALOGE("failed to call callback, error: %s, code: %d", callbackStatus.getMessage(), callbackStatus.getServiceSpecificError()); } } // Send all the GetValue/SetValue results through callback, one result in each callback invocation. template void sendGetOrSetValueResultsSeparately(std::shared_ptr callback, const std::vector& results) { for (const auto& result : results) { sendGetOrSetValueResult(callback, result); } } // Send all the GetValue/SetValue results through callback in a single callback invocation. template void sendGetOrSetValueResults(std::shared_ptr callback, const std::vector& results) { ResultsType parcelableResults; ScopedAStatus status = vectorToStableLargeParcelable(results, &parcelableResults); if (status.isOk()) { if (ScopedAStatus callbackStatus = callCallback(callback, parcelableResults); !callbackStatus.isOk()) { ALOGE("failed to call callback, error: %s, code: %d", status.getMessage(), status.getServiceSpecificError()); } return; } int statusCode = status.getServiceSpecificError(); ALOGE("failed to marshal result into large parcelable, error: " "%s, code: %d", status.getMessage(), statusCode); sendGetOrSetValueResultsSeparately(callback, results); } // Specify the functions for GetValues and SetValues types. template void sendGetOrSetValueResult( std::shared_ptr callback, const GetValueResult& result); template void sendGetOrSetValueResult( std::shared_ptr callback, const SetValueResult& result); template void sendGetOrSetValueResults( std::shared_ptr callback, const std::vector& results); template void sendGetOrSetValueResults( std::shared_ptr callback, const std::vector& results); template void sendGetOrSetValueResultsSeparately( std::shared_ptr callback, const std::vector& results); template void sendGetOrSetValueResultsSeparately( std::shared_ptr callback, const std::vector& results); } // namespace ConnectedClient::ConnectedClient(std::shared_ptr callback) : mCallback(callback) {} template GetSetValuesClient::GetSetValuesClient( std::shared_ptr callback) : ConnectedClient(callback) { mResultCallback = std::make_shared)>>( [callback](std::vector results) { return sendGetOrSetValueResults(callback, results); }); } template std::shared_ptr)>> GetSetValuesClient::getResultCallback() { return mResultCallback; } template void GetSetValuesClient::sendResults( const std::vector& results) { return sendGetOrSetValueResults(mCallback, results); } template void GetSetValuesClient::sendResultsSeparately( const std::vector& results) { return sendGetOrSetValueResultsSeparately(mCallback, results); } template class GetSetValuesClient; template class GetSetValuesClient; } // namespace vehicle } // namespace automotive } // namespace hardware } // namespace android