/** * 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. */ #ifndef CPP_POWERPOLICY_SERVER_SRC_CARPOWERPOLICYSERVER_H_ #define CPP_POWERPOLICY_SERVER_SRC_CARPOWERPOLICYSERVER_H_ #include "PolicyManager.h" #include "PowerComponentHandler.h" #include "SilentModeHandler.h" #include #include #include #include #include #include #include #include #include #include #include #include #include namespace android { namespace frameworks { namespace automotive { namespace powerpolicy { struct CallbackInfo { CallbackInfo(const android::sp& callback, const CarPowerPolicyFilter& filter, int32_t pid) : callback(callback), filter(filter), pid(pid) {} android::sp callback; CarPowerPolicyFilter filter; pid_t pid; }; // Forward declaration for testing use only. namespace internal { class CarPowerPolicyServerPeer; } // namespace internal // Forward declaration for defining binder death handler and property change listener. class CarPowerPolicyServer; class BinderDeathRecipient : public android::IBinder::DeathRecipient { public: explicit BinderDeathRecipient(const android::sp& service); void binderDied(const android::wp& who) override; private: android::sp mService; }; class HidlDeathRecipient : public android::hardware::hidl_death_recipient { public: explicit HidlDeathRecipient(const android::sp& service); void serviceDied(uint64_t cookie, const android::wp& who) override; private: sp mService; }; class PropertyChangeListener : public android::hardware::automotive::vehicle::V2_0::IVehicleCallback { public: explicit PropertyChangeListener(const android::sp& service); android::hardware::Return onPropertyEvent( const android::hardware::hidl_vec< hardware::automotive::vehicle::V2_0::VehiclePropValue>& propValues) override; android::hardware::Return onPropertySet( const android::hardware::automotive::vehicle::V2_0::VehiclePropValue& propValue); android::hardware::Return onPropertySetError( android::hardware::automotive::vehicle::V2_0::StatusCode status, int32_t propId, int32_t areaId); private: android::sp mService; }; class MessageHandlerImpl : public android::MessageHandler { public: explicit MessageHandlerImpl(const android::sp& service); void handleMessage(const android::Message& message) override; private: android::sp mService; }; class CarServiceNotificationHandler : public android::frameworks::automotive::powerpolicy::internal:: BnCarPowerPolicySystemNotification { public: explicit CarServiceNotificationHandler(const android::sp& server); android::status_t dump(int fd, const android::Vector& args) override; android::binder::Status notifyCarServiceReady( android::frameworks::automotive::powerpolicy::internal::PolicyState* policyState) override; android::binder::Status notifyPowerPolicyChange(const std::string& policyId, bool force) override; android::binder::Status notifyPowerPolicyDefinition( const std::string& policyId, const std::vector& enabledComponents, const std::vector& disabledComponents) override; private: android::sp mService; }; /** * ISilentModeChangeHandler defines a method which is called when a Silent Mode hw state is changed. */ class ISilentModeChangeHandler { public: virtual ~ISilentModeChangeHandler() = 0; // Called when Silent Mode is changed. virtual void notifySilentModeChange(const bool isSilent) = 0; }; /** * CarPowerPolicyServer implements ISilentModeChangeHandler and ICarPowerPolicyServer.aidl. * It handles power policy requests and Silent Mode before Android framework takes control of the * device. */ class CarPowerPolicyServer final : public ISilentModeChangeHandler, public BnCarPowerPolicyServer { public: static base::Result> startService(const sp& looper); static void terminateService(); // Implements ICarPowerPolicyServer.aidl. status_t dump(int fd, const Vector& args) override; binder::Status getCurrentPowerPolicy(CarPowerPolicy* aidlReturn) override; binder::Status getPowerComponentState(PowerComponent componentId, bool* aidlReturn) override; binder::Status registerPowerPolicyChangeCallback( const android::sp& callback, const CarPowerPolicyFilter& filter) override; binder::Status unregisterPowerPolicyChangeCallback( const android::sp& callback) override; void connectToVhalHelper(); void handleBinderDeath(const android::wp& who); void handleHidlDeath(const android::wp& who); // Implements ICarPowerPolicySystemNotification.aidl. android::binder::Status notifyCarServiceReady( android::frameworks::automotive::powerpolicy::internal::PolicyState* policyState); android::binder::Status notifyPowerPolicyChange(const std::string& policyId, bool force); android::binder::Status notifyPowerPolicyDefinition( const std::string& policyId, const std::vector& enabledComponents, const std::vector& disabledComponents); /** * Applies the given power policy. * * @param carServiceInOperation expected Car Service running state. * @param force whether to apply the policy even when the current policy is a system * power policy. */ android::base::Result applyPowerPolicy(const std::string& policyId, const bool carServiceInOperation, const bool force); /** * Sets the power policy group which contains rules to map a power state to a default power * policy to apply. */ android::base::Result setPowerPolicyGroup(const std::string& groupId); // Implements ISilentModeChangeHandler. void notifySilentModeChange(const bool isSilent); private: CarPowerPolicyServer(); android::base::Result init(const android::sp& looper); void terminate(); bool isRegisteredLocked(const android::sp& callback); void connectToVhal(); void applyInitialPowerPolicy(); void subscribeToVhal(); void subscribeToProperty( int32_t prop, std::function< void(const android::hardware::automotive::vehicle::V2_0::VehiclePropValue&)> processor); android::base::Result notifyVhalNewPowerPolicy(const std::string& policyId); bool isPropertySupported(const int32_t prop); bool isPowerPolicyAppliedLocked() const; private: static android::sp sCarPowerPolicyServer; sp mHandlerLooper; sp mMessageHandler; PowerComponentHandler mComponentHandler; PolicyManager mPolicyManager; SilentModeHandler mSilentModeHandler; android::Mutex mMutex; CarPowerPolicyMeta mCurrentPowerPolicyMeta GUARDED_BY(mMutex); std::string mCurrentPolicyGroupId GUARDED_BY(mMutex); std::string mPendingPowerPolicyId GUARDED_BY(mMutex); bool mIsPowerPolicyLocked GUARDED_BY(mMutex); std::vector mPolicyChangeCallbacks GUARDED_BY(mMutex); android::sp mVhalService GUARDED_BY(mMutex); std::optional mLastApplyPowerPolicyUptimeMs GUARDED_BY(mMutex); std::optional mLastSetDefaultPowerPolicyGroupUptimeMs GUARDED_BY(mMutex); bool mIsCarServiceInOperation GUARDED_BY(mMutex); // No thread-safety guard is needed because only accessed through main thread handler. bool mIsFirstConnectionToVhal; std::unordered_map mSupportedProperties; android::sp mBinderDeathRecipient; android::sp mHidlDeathRecipient; android::sp mPropertyChangeListener; android::sp mCarServiceNotificationHandler; int32_t mRemainingConnectionRetryCount; // For unit tests. friend class android::frameworks::automotive::powerpolicy::internal::CarPowerPolicyServerPeer; }; } // namespace powerpolicy } // namespace automotive } // namespace frameworks } // namespace android #endif // CPP_POWERPOLICY_SERVER_SRC_CARPOWERPOLICYSERVER_H_