1 /** 2 * Copyright (c) 2020, 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 */ 16 17 #ifndef CPP_POWERPOLICY_SERVER_SRC_CARPOWERPOLICYSERVER_H_ 18 #define CPP_POWERPOLICY_SERVER_SRC_CARPOWERPOLICYSERVER_H_ 19 20 #include "PolicyManager.h" 21 #include "PowerComponentHandler.h" 22 #include "SilentModeHandler.h" 23 24 #include <aidl/android/frameworks/automotive/powerpolicy/BnCarPowerPolicyServer.h> 25 #include <aidl/android/frameworks/automotive/powerpolicy/internal/BnCarPowerPolicySystemNotification.h> 26 #include <android-base/result.h> 27 #include <binder/IBinder.h> 28 #include <binder/Status.h> 29 #include <utils/Looper.h> 30 #include <utils/Mutex.h> 31 #include <utils/String16.h> 32 #include <utils/StrongPointer.h> 33 #include <utils/Vector.h> 34 35 #include <IVhalClient.h> 36 37 #include <optional> 38 #include <unordered_set> 39 40 namespace android { 41 namespace frameworks { 42 namespace automotive { 43 namespace powerpolicy { 44 45 struct CallbackInfo { CallbackInfoCallbackInfo46 CallbackInfo(::ndk::SpAIBinder binder, 47 const ::aidl::android::frameworks::automotive::powerpolicy::CarPowerPolicyFilter& 48 filter, 49 int32_t pid) : 50 binder(binder), filter(filter), pid(pid) {} 51 52 ::ndk::SpAIBinder binder; 53 ::aidl::android::frameworks::automotive::powerpolicy::CarPowerPolicyFilter filter; 54 pid_t pid; 55 }; 56 57 // Forward declaration for testing use only. 58 namespace internal { 59 60 class CarPowerPolicyServerPeer; 61 62 } // namespace internal 63 64 // Forward declaration for defining binder death handler and property change listener. 65 class CarPowerPolicyServer; 66 67 class PropertyChangeListener final : 68 public android::frameworks::automotive::vhal::ISubscriptionCallback { 69 public: 70 explicit PropertyChangeListener(CarPowerPolicyServer* service); 71 72 void onPropertyEvent(const std::vector< 73 std::unique_ptr<android::frameworks::automotive::vhal::IHalPropValue>>& 74 values) override; 75 76 void onPropertySetError(const std::vector<android::frameworks::automotive::vhal::HalPropError>& 77 errors) override; 78 79 private: 80 CarPowerPolicyServer* mService; 81 }; 82 83 class MessageHandlerImpl : public android::MessageHandler { 84 public: 85 explicit MessageHandlerImpl(CarPowerPolicyServer* service); 86 87 void handleMessage(const android::Message& message) override; 88 89 private: 90 CarPowerPolicyServer* mService; 91 }; 92 93 class CarServiceNotificationHandler : 94 public ::aidl::android::frameworks::automotive::powerpolicy::internal:: 95 BnCarPowerPolicySystemNotification { 96 public: 97 explicit CarServiceNotificationHandler(CarPowerPolicyServer* server); 98 99 binder_status_t dump(int fd, const char** args, uint32_t numArgs) override; 100 ::ndk::ScopedAStatus notifyCarServiceReady( 101 ::aidl::android::frameworks::automotive::powerpolicy::internal::PolicyState* 102 policyState) override; 103 ::ndk::ScopedAStatus notifyPowerPolicyChange(const std::string& policyId, bool force) override; 104 ::ndk::ScopedAStatus notifyPowerPolicyDefinition( 105 const std::string& policyId, const std::vector<std::string>& enabledComponents, 106 const std::vector<std::string>& disabledComponents) override; 107 108 void terminate(); 109 110 private: 111 android::Mutex mMutex; 112 CarPowerPolicyServer* mService GUARDED_BY(mMutex); 113 }; 114 115 /** 116 * ISilentModeChangeHandler defines a method which is called when a Silent Mode hw state is changed. 117 */ 118 class ISilentModeChangeHandler { 119 public: 120 virtual ~ISilentModeChangeHandler() = 0; 121 122 // Called when Silent Mode is changed. 123 virtual void notifySilentModeChange(const bool isSilent) = 0; 124 }; 125 126 /** 127 * CarPowerPolicyServer implements ISilentModeChangeHandler and ICarPowerPolicyServer.aidl. 128 * It handles power policy requests and Silent Mode before Android framework takes control of the 129 * device. 130 */ 131 class CarPowerPolicyServer final : 132 public ISilentModeChangeHandler, 133 public ::aidl::android::frameworks::automotive::powerpolicy::BnCarPowerPolicyServer { 134 public: 135 static base::Result<std::shared_ptr<CarPowerPolicyServer>> startService( 136 const sp<android::Looper>& looper); 137 static void terminateService(); 138 139 // Implements ICarPowerPolicyServer.aidl. 140 status_t dump(int fd, const char** args, uint32_t numArgs) override; 141 ::ndk::ScopedAStatus getCurrentPowerPolicy( 142 ::aidl::android::frameworks::automotive::powerpolicy::CarPowerPolicy* aidlReturn) 143 override; 144 ::ndk::ScopedAStatus getPowerComponentState( 145 ::aidl::android::frameworks::automotive::powerpolicy::PowerComponent componentId, 146 bool* aidlReturn) override; 147 ::ndk::ScopedAStatus registerPowerPolicyChangeCallback( 148 const std::shared_ptr<aidl::android::frameworks::automotive::powerpolicy:: 149 ICarPowerPolicyChangeCallback>& callback, 150 const ::aidl::android::frameworks::automotive::powerpolicy::CarPowerPolicyFilter& 151 filter) override; 152 ::ndk::ScopedAStatus unregisterPowerPolicyChangeCallback( 153 const std::shared_ptr<aidl::android::frameworks::automotive::powerpolicy:: 154 ICarPowerPolicyChangeCallback>& callback) override; 155 156 void connectToVhalHelper(); 157 void handleBinderDeath(const AIBinder* client); 158 void handleVhalDeath(); 159 160 // Implements ICarPowerPolicySystemNotification.aidl. 161 ::ndk::ScopedAStatus notifyCarServiceReady( 162 ::aidl::android::frameworks::automotive::powerpolicy::internal::PolicyState* 163 policyState); 164 ::ndk::ScopedAStatus notifyPowerPolicyChange(const std::string& policyId, bool force); 165 ::ndk::ScopedAStatus notifyPowerPolicyDefinition( 166 const std::string& policyId, const std::vector<std::string>& enabledComponents, 167 const std::vector<std::string>& disabledComponents); 168 169 /** 170 * Applies the given power policy. 171 * 172 * @param carServiceInOperation expected Car Service running state. 173 * @param force whether to apply the policy even when the current policy is a system 174 * power policy. 175 */ 176 android::base::Result<void> applyPowerPolicy(const std::string& policyId, 177 const bool carServiceInOperation, 178 const bool force); 179 /** 180 * Sets the power policy group which contains rules to map a power state to a default power 181 * policy to apply. 182 */ 183 android::base::Result<void> setPowerPolicyGroup(const std::string& groupId); 184 185 // Implements ISilentModeChangeHandler. 186 void notifySilentModeChange(const bool isSilent); 187 188 private: 189 friend class ::ndk::SharedRefBase; 190 191 // OnBinderDiedContext is a type used as a cookie passed deathRecipient. The deathRecipient's 192 // onBinderDied function takes only a cookie as input and we have to store all the contexts 193 // as the cookie. 194 struct OnBinderDiedContext { 195 CarPowerPolicyServer* server; 196 const AIBinder* clientId; 197 }; 198 199 class LinkUnlinkImpl { 200 public: 201 virtual ~LinkUnlinkImpl() = default; 202 203 virtual binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, 204 void* cookie) = 0; 205 virtual binder_status_t unlinkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, 206 void* cookie) = 0; 207 }; 208 209 class AIBinderLinkUnlinkImpl final : public LinkUnlinkImpl { 210 public: 211 binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, 212 void* cookie) override; 213 binder_status_t unlinkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, 214 void* cookie) override; 215 }; 216 217 CarPowerPolicyServer(); 218 219 void terminate(); 220 bool isRegisteredLocked(const AIBinder* binder); 221 void connectToVhal(); 222 void applyInitialPowerPolicy(); 223 void subscribeToVhal(); 224 void subscribeToProperty( 225 int32_t prop, 226 std::function<void(const android::frameworks::automotive::vhal::IHalPropValue&)> 227 processor); 228 android::base::Result<void> notifyVhalNewPowerPolicy(const std::string& policyId); 229 bool isPropertySupported(const int32_t prop); 230 bool isPowerPolicyAppliedLocked() const; 231 android::base::Result<void> init(const sp<android::Looper>& looper); 232 233 static void onBinderDied(void* cookie); 234 static std::string callbackToString(const CallbackInfo& callback); 235 236 // For test-only. 237 void setLinkUnlinkImpl(std::unique_ptr<LinkUnlinkImpl> impl); 238 std::vector<CallbackInfo> getPolicyChangeCallbacks(); 239 size_t countOnBinderDiedContexts(); 240 241 private: 242 static std::shared_ptr<CarPowerPolicyServer> sCarPowerPolicyServer; 243 244 sp<android::Looper> mHandlerLooper; 245 sp<MessageHandlerImpl> mMessageHandler; 246 PowerComponentHandler mComponentHandler; 247 PolicyManager mPolicyManager; 248 SilentModeHandler mSilentModeHandler; 249 android::Mutex mMutex; 250 CarPowerPolicyMeta mCurrentPowerPolicyMeta GUARDED_BY(mMutex); 251 std::string mCurrentPolicyGroupId GUARDED_BY(mMutex); 252 std::string mPendingPowerPolicyId GUARDED_BY(mMutex); 253 bool mIsPowerPolicyLocked GUARDED_BY(mMutex); 254 std::vector<CallbackInfo> mPolicyChangeCallbacks GUARDED_BY(mMutex); 255 std::shared_ptr<android::frameworks::automotive::vhal::IVhalClient> mVhalService 256 GUARDED_BY(mMutex); 257 std::optional<int64_t> mLastApplyPowerPolicyUptimeMs GUARDED_BY(mMutex); 258 std::optional<int64_t> mLastSetDefaultPowerPolicyGroupUptimeMs GUARDED_BY(mMutex); 259 bool mIsCarServiceInOperation GUARDED_BY(mMutex); 260 // No thread-safety guard is needed because only accessed through main thread handler. 261 bool mIsFirstConnectionToVhal; 262 std::unordered_map<int32_t, bool> mSupportedProperties; 263 ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient GUARDED_BY(mMutex); 264 // Thread-safe because only initialized once. 265 std::shared_ptr<PropertyChangeListener> mPropertyChangeListener; 266 std::unique_ptr<android::frameworks::automotive::vhal::ISubscriptionClient> mSubscriptionClient; 267 std::shared_ptr<CarServiceNotificationHandler> mCarServiceNotificationHandler 268 GUARDED_BY(mMutex); 269 int32_t mRemainingConnectionRetryCount; 270 // A stub for link/unlink operation. Can be replaced with mock implementation for testing. 271 // Thread-safe because only initialized once or modified in test. 272 std::unique_ptr<LinkUnlinkImpl> mLinkUnlinkImpl; 273 274 // A map of callback ptr to context that is required for handleBinderDeath. 275 std::unordered_map<const AIBinder*, std::unique_ptr<OnBinderDiedContext>> mOnBinderDiedContexts 276 GUARDED_BY(mMutex); 277 278 // For unit tests. 279 friend class android::frameworks::automotive::powerpolicy::internal::CarPowerPolicyServerPeer; 280 }; 281 282 } // namespace powerpolicy 283 } // namespace automotive 284 } // namespace frameworks 285 } // namespace android 286 287 #endif // CPP_POWERPOLICY_SERVER_SRC_CARPOWERPOLICYSERVER_H_ 288