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/automotive/powerpolicy/internal/BnCarPowerPolicyDelegate.h> 25 #include <aidl/android/automotive/powerpolicy/internal/PowerPolicyInitData.h> 26 #include <aidl/android/frameworks/automotive/powerpolicy/BnCarPowerPolicyServer.h> 27 #include <aidl/android/frameworks/automotive/powerpolicy/internal/BnCarPowerPolicySystemNotification.h> 28 #include <android-base/result.h> 29 #include <binder/IBinder.h> 30 #include <binder/Status.h> 31 #include <utils/Looper.h> 32 #include <utils/String16.h> 33 #include <utils/StrongPointer.h> 34 #include <utils/Vector.h> 35 36 #include <IVhalClient.h> 37 38 #include <condition_variable> // NOLINT 39 #include <mutex> // NOLINT 40 #include <optional> 41 #include <unordered_set> 42 43 namespace android { 44 namespace frameworks { 45 namespace automotive { 46 namespace powerpolicy { 47 48 struct CallbackInfo { CallbackInfoCallbackInfo49 CallbackInfo( 50 ndk::SpAIBinder binder, 51 const aidl::android::frameworks::automotive::powerpolicy::CarPowerPolicyFilter& filter, 52 int32_t pid) : 53 binder(binder), filter(filter), pid(pid) {} 54 55 ndk::SpAIBinder binder; 56 aidl::android::frameworks::automotive::powerpolicy::CarPowerPolicyFilter filter; 57 pid_t pid; 58 }; 59 60 // Forward declaration for testing use only. 61 namespace internal { 62 63 class CarPowerPolicyServerPeer; 64 65 } // namespace internal 66 67 // Forward declaration for defining binder death handler and property change listener. 68 class CarPowerPolicyServer; 69 70 class PropertyChangeListener final : 71 public android::frameworks::automotive::vhal::ISubscriptionCallback { 72 public: 73 explicit PropertyChangeListener(CarPowerPolicyServer* service); 74 75 void onPropertyEvent(const std::vector< 76 std::unique_ptr<android::frameworks::automotive::vhal::IHalPropValue>>& 77 values) override; 78 79 void onPropertySetError(const std::vector<android::frameworks::automotive::vhal::HalPropError>& 80 errors) override; 81 82 private: 83 CarPowerPolicyServer* mService; 84 }; 85 86 class EventHandler : public android::MessageHandler { 87 public: 88 explicit EventHandler(CarPowerPolicyServer* service); 89 90 void handleMessage(const android::Message& message) override; 91 92 private: 93 CarPowerPolicyServer* mService; 94 }; 95 96 class RequestIdHandler : public android::MessageHandler { 97 public: 98 explicit RequestIdHandler(CarPowerPolicyServer* service); 99 100 void handleMessage(const android::Message& message) override; 101 102 private: 103 CarPowerPolicyServer* mService; 104 }; 105 106 // TODO(b/301025020): Remove CarServiceNotificationHandler once CarPowerPolicyDelegate is ready. 107 class CarServiceNotificationHandler : 108 public aidl::android::frameworks::automotive::powerpolicy::internal:: 109 BnCarPowerPolicySystemNotification { 110 public: 111 explicit CarServiceNotificationHandler(CarPowerPolicyServer* server); 112 113 binder_status_t dump(int fd, const char** args, uint32_t numArgs) override EXCLUDES(mMutex); 114 ndk::ScopedAStatus notifyCarServiceReady( 115 aidl::android::frameworks::automotive::powerpolicy::internal::PolicyState* policyState) 116 override EXCLUDES(mMutex); 117 ndk::ScopedAStatus notifyPowerPolicyChange(const std::string& policyId, bool force) override 118 EXCLUDES(mMutex); 119 ndk::ScopedAStatus notifyPowerPolicyDefinition( 120 const std::string& policyId, const std::vector<std::string>& enabledComponents, 121 const std::vector<std::string>& disabledComponents) override EXCLUDES(mMutex); 122 123 void terminate() EXCLUDES(mMutex); 124 125 private: 126 std::mutex mMutex; 127 CarPowerPolicyServer* mService GUARDED_BY(mMutex); 128 }; 129 130 class CarPowerPolicyDelegate final : 131 public aidl::android::automotive::powerpolicy::internal::BnCarPowerPolicyDelegate { 132 public: 133 explicit CarPowerPolicyDelegate(CarPowerPolicyServer* service); 134 135 binder_status_t dump(int fd, const char** args, uint32_t numArgs) override EXCLUDES(mMutex); 136 ndk::ScopedAStatus notifyCarServiceReady( 137 const std::shared_ptr<aidl::android::automotive::powerpolicy::internal:: 138 ICarPowerPolicyDelegateCallback>& callback, 139 aidl::android::automotive::powerpolicy::internal::PowerPolicyInitData* aidlReturn) 140 override; 141 ndk::ScopedAStatus applyPowerPolicyAsync(int32_t requestId, const std::string& policyId, 142 bool force) override EXCLUDES(mMutex); 143 ndk::ScopedAStatus setPowerPolicyGroup(const std::string& policyGroupId) override 144 EXCLUDES(mMutex); 145 ndk::ScopedAStatus notifyPowerPolicyDefinition( 146 const std::string& policyId, const std::vector<std::string>& enabledComponents, 147 const std::vector<std::string>& disabledComponents) override EXCLUDES(mMutex); 148 ndk::ScopedAStatus notifyPowerPolicyGroupDefinition( 149 const std::string& policyGroupId, 150 const std::vector<std::string>& powerPolicyPerState) override; 151 ndk::ScopedAStatus applyPowerPolicyPerPowerStateChangeAsync( 152 int32_t requestId, 153 aidl::android::automotive::powerpolicy::internal::ICarPowerPolicyDelegate::PowerState 154 state) override; 155 ndk::ScopedAStatus setSilentMode(const std::string& silentMode) override; 156 157 void terminate() EXCLUDES(mMutex); 158 ndk::ScopedAStatus runWithService( 159 const std::function<ndk::ScopedAStatus(CarPowerPolicyServer*)>& action, 160 const std::string& actionTitle) EXCLUDES(mMutex); 161 162 private: 163 std::mutex mMutex; 164 CarPowerPolicyServer* mService GUARDED_BY(mMutex); 165 }; 166 167 /** 168 * ISilentModeChangeHandler defines a method which is called when a Silent Mode hw state is changed. 169 */ 170 class ISilentModeChangeHandler { 171 public: 172 virtual ~ISilentModeChangeHandler() = 0; 173 174 // Called when Silent Mode is changed. 175 virtual void notifySilentModeChange(const bool isSilent) = 0; 176 }; 177 178 /** 179 * CarPowerPolicyServer implements ISilentModeChangeHandler and ICarPowerPolicyServer.aidl. 180 * It handles power policy requests and Silent Mode before Android framework takes control of the 181 * device. 182 */ 183 class CarPowerPolicyServer final : 184 public ISilentModeChangeHandler, 185 public aidl::android::frameworks::automotive::powerpolicy::BnCarPowerPolicyServer { 186 public: 187 static android::base::Result<std::shared_ptr<CarPowerPolicyServer>> startService( 188 const android::sp<android::Looper>& looper); 189 static void terminateService(); 190 191 CarPowerPolicyServer(); 192 ~CarPowerPolicyServer(); 193 android::base::Result<void> init(const sp<android::Looper>& looper); 194 195 // Implements ICarPowerPolicyServer.aidl. 196 status_t dump(int fd, const char** args, uint32_t numArgs) override EXCLUDES(mMutex); 197 ndk::ScopedAStatus getCurrentPowerPolicy( 198 aidl::android::frameworks::automotive::powerpolicy::CarPowerPolicy* aidlReturn) override 199 EXCLUDES(mMutex); 200 ndk::ScopedAStatus getPowerComponentState( 201 aidl::android::frameworks::automotive::powerpolicy::PowerComponent componentId, 202 bool* aidlReturn) override; 203 ndk::ScopedAStatus registerPowerPolicyChangeCallback( 204 const std::shared_ptr<aidl::android::frameworks::automotive::powerpolicy:: 205 ICarPowerPolicyChangeCallback>& callback, 206 const aidl::android::frameworks::automotive::powerpolicy::CarPowerPolicyFilter& filter) 207 override EXCLUDES(mMutex); 208 ndk::ScopedAStatus unregisterPowerPolicyChangeCallback( 209 const std::shared_ptr<aidl::android::frameworks::automotive::powerpolicy:: 210 ICarPowerPolicyChangeCallback>& callback) override 211 EXCLUDES(mMutex); 212 ndk::ScopedAStatus applyPowerPolicy(const std::string& policyId) override EXCLUDES(mMutex); 213 ndk::ScopedAStatus setPowerPolicyGroup(const std::string& policyGroupId) override; 214 215 // Implements ICarPowerPolicySystemNotification.aidl. 216 ndk::ScopedAStatus notifyCarServiceReady( 217 aidl::android::frameworks::automotive::powerpolicy::internal::PolicyState* policyState) 218 EXCLUDES(mMutex); 219 ndk::ScopedAStatus notifyPowerPolicyChange(const std::string& policyId, bool force); 220 ndk::ScopedAStatus notifyPowerPolicyDefinition( 221 const std::string& policyId, const std::vector<std::string>& enabledComponents, 222 const std::vector<std::string>& disabledComponents); 223 ndk::ScopedAStatus notifyPowerPolicyGroupDefinition( 224 const std::string& policyGroupId, const std::vector<std::string>& powerPolicyPerState); 225 ndk::ScopedAStatus applyPowerPolicyPerPowerStateChangeAsync( 226 int32_t requestId, 227 aidl::android::automotive::powerpolicy::internal::ICarPowerPolicyDelegate::PowerState 228 state); 229 ndk::ScopedAStatus setSilentMode(const std::string& silentMode); 230 231 // Internal implementation of ICarPowerPolicyDelegate.aidl. 232 ndk::ScopedAStatus applyPowerPolicyAsync(int32_t requestId, const std::string& policyId, 233 bool force); 234 ndk::ScopedAStatus notifyCarServiceReadyInternal( 235 const std::shared_ptr<aidl::android::automotive::powerpolicy::internal:: 236 ICarPowerPolicyDelegateCallback>& callback, 237 aidl::android::automotive::powerpolicy::internal::PowerPolicyInitData* aidlReturn); 238 239 // Implements ISilentModeChangeHandler. 240 void notifySilentModeChange(const bool isSilent); 241 242 /** 243 * Applies the given power policy. 244 * 245 * @param policyId ID of a power policy to apply. 246 * @param carServiceInOperation expected Car Service running state. 247 * @param force whether to apply the policy even when the current policy is a system 248 * power policy. 249 */ 250 android::base::Result<void> applyPowerPolicy(const std::string& policyId, 251 const bool carServiceInOperation, const bool force) 252 EXCLUDES(mMutex); 253 /** 254 * Sets the power policy group which contains rules to map a power state to a default power 255 * policy to apply. 256 */ 257 android::base::Result<void> setPowerPolicyGroupInternal(const std::string& groupId) 258 EXCLUDES(mMutex); 259 260 void connectToVhalHelper() EXCLUDES(mMutex); 261 void handleClientBinderDeath(const AIBinder* client) EXCLUDES(mMutex); 262 void handleCarServiceBinderDeath() EXCLUDES(mMutex); 263 void handleVhalDeath() EXCLUDES(mMutex); 264 void handleApplyPowerPolicyRequest(const int32_t requestId); 265 266 private: 267 friend class ndk::SharedRefBase; 268 269 // OnClientBinderDiedContext is a type used as a cookie passed deathRecipient. The 270 // deathRecipient's onClientBinderDied function takes only a cookie as input and we have to 271 // store all the contexts as the cookie. 272 struct OnClientBinderDiedContext { 273 CarPowerPolicyServer* server; 274 const AIBinder* clientId; 275 }; 276 277 class LinkUnlinkImpl { 278 public: 279 virtual ~LinkUnlinkImpl() = default; 280 281 virtual binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, 282 void* cookie) = 0; 283 virtual binder_status_t unlinkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, 284 void* cookie) = 0; 285 virtual void setOnUnlinked(AIBinder_DeathRecipient* recipient, 286 AIBinder_DeathRecipient_onBinderUnlinked onUnlinked) = 0; 287 virtual void deleteDeathRecipient(AIBinder_DeathRecipient* recipient) = 0; 288 }; 289 290 class AIBinderLinkUnlinkImpl final : public LinkUnlinkImpl { 291 public: 292 binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, 293 void* cookie) override; 294 binder_status_t unlinkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, 295 void* cookie) override; 296 void setOnUnlinked(AIBinder_DeathRecipient* recipient, 297 AIBinder_DeathRecipient_onBinderUnlinked onUnlinked) override; 298 void deleteDeathRecipient(AIBinder_DeathRecipient* recipient) override; 299 }; 300 301 struct PolicyRequest { 302 std::string policyId; 303 bool force; 304 }; 305 306 void terminate() EXCLUDES(mMutex); 307 bool isRegisteredLocked(const AIBinder* binder) REQUIRES(mMutex); 308 void connectToVhal(); 309 void subscribeToVhal(); 310 void subscribeToProperty( 311 int32_t prop, 312 std::function<void(const android::frameworks::automotive::vhal::IHalPropValue&)> 313 processor) EXCLUDES(mMutex); 314 bool isPropertySupported(const int32_t prop) EXCLUDES(mMutex); 315 bool isPowerPolicyAppliedLocked() const REQUIRES(mMutex); 316 bool canApplyPowerPolicyLocked(const CarPowerPolicyMeta& policyMeta, const bool force, 317 std::vector<CallbackInfo>& outClients) REQUIRES(mMutex); 318 void applyInitialPowerPolicy() EXCLUDES(mMutex); 319 void applyAndNotifyPowerPolicy(const CarPowerPolicyMeta& policyMeta, 320 const std::vector<CallbackInfo>& clients, 321 const bool notifyCarService); 322 // Returns true if the application is done, false if it is deferred. 323 android::base::Result<bool> applyPowerPolicyInternal(const std::string& policyId, 324 const bool force, 325 const bool notifyCarService) 326 EXCLUDES(mMutex); 327 android::base::Result<void> notifyVhalNewPowerPolicy(const std::string& policyId) 328 EXCLUDES(mMutex); 329 ndk::ScopedAStatus enqueuePowerPolicyRequest(int32_t requestId, const std::string& policyId, 330 bool force) EXCLUDES(mMutex); 331 void notifySilentModeChangeInternal(const bool isSilent) EXCLUDES(mMutex); 332 void notifySilentModeChangeLegacy(const bool isSilent) EXCLUDES(mMutex); 333 void setOnUnlinked(); 334 void handleClientDeathRecipientUnlinked(const AIBinder* clientId); 335 void handleCarServiceDeathRecipientUnlinked(); 336 337 static void onClientBinderDied(void* cookie); 338 static void onCarServiceBinderDied(void* cookie); 339 static std::string callbackToString(const CallbackInfo& callback); 340 static void onCarServiceDeathRecipientUnlinked(void* cookie); 341 static void onClientDeathRecipientUnlinked(void* cookie); 342 343 // For test-only. 344 void setLinkUnlinkImpl(std::unique_ptr<LinkUnlinkImpl> impl); 345 std::vector<CallbackInfo> getPolicyChangeCallbacks() EXCLUDES(mMutex); 346 size_t countOnClientBinderDiedContexts() EXCLUDES(mMutex); 347 348 private: 349 static std::shared_ptr<CarPowerPolicyServer> sCarPowerPolicyServer; 350 351 ndk::ScopedAIBinder_DeathRecipient mClientDeathRecipient; 352 ndk::ScopedAIBinder_DeathRecipient mCarServiceDeathRecipient; 353 android::sp<android::Looper> mHandlerLooper; 354 android::sp<EventHandler> mEventHandler; 355 android::sp<RequestIdHandler> mRequestIdHandler; 356 PowerComponentHandler mComponentHandler; 357 PolicyManager mPolicyManager; 358 SilentModeHandler mSilentModeHandler; 359 std::mutex mMutex; 360 CarPowerPolicyMeta mCurrentPowerPolicyMeta GUARDED_BY(mMutex); 361 std::string mCurrentPolicyGroupId GUARDED_BY(mMutex); 362 std::string mPendingPowerPolicyId GUARDED_BY(mMutex); 363 bool mIsPowerPolicyLocked GUARDED_BY(mMutex); 364 std::vector<CallbackInfo> mPolicyChangeCallbacks GUARDED_BY(mMutex); 365 std::shared_ptr<android::frameworks::automotive::vhal::IVhalClient> mVhalService 366 GUARDED_BY(mMutex); 367 std::optional<int64_t> mLastApplyPowerPolicyUptimeMs GUARDED_BY(mMutex); 368 std::optional<int64_t> mLastSetDefaultPowerPolicyGroupUptimeMs GUARDED_BY(mMutex); 369 bool mIsCarServiceInOperation GUARDED_BY(mMutex); 370 // No thread-safety guard is needed because only accessed through main thread handler. 371 bool mIsFirstConnectionToVhal; 372 std::unordered_map<int32_t, bool> mSupportedProperties; 373 // Thread-safe because only initialized once. 374 std::shared_ptr<PropertyChangeListener> mPropertyChangeListener; 375 std::unique_ptr<android::frameworks::automotive::vhal::ISubscriptionClient> mSubscriptionClient; 376 std::shared_ptr<CarServiceNotificationHandler> mCarServiceNotificationHandler 377 GUARDED_BY(mMutex); 378 int32_t mRemainingConnectionRetryCount; 379 // A stub for link/unlink operation. Can be replaced with mock implementation for testing. 380 // Thread-safe because only initialized once or modified in test. 381 std::unique_ptr<LinkUnlinkImpl> mLinkUnlinkImpl; 382 383 std::shared_ptr<CarPowerPolicyDelegate> mCarPowerPolicyDelegate GUARDED_BY(mMutex); 384 ndk::SpAIBinder mPowerPolicyDelegateCallback GUARDED_BY(mMutex); 385 386 // A map of callback ptr to context that is required for handleClientBinderDeath. 387 std::unordered_map<const AIBinder*, std::unique_ptr<OnClientBinderDiedContext>> 388 mOnClientBinderDiedContexts GUARDED_BY(mMutex); 389 std::unordered_map<uint32_t, PolicyRequest> mPolicyRequestById GUARDED_BY(mMutex); 390 bool mCarServiceLinked GUARDED_BY(mMutex) = false; 391 // A cv to indicate whether all resources used through pointer via death recipients 392 // are okay to be released. This cv is protected by mMutex. 393 std::condition_variable mResourceReleasedCv; 394 395 // For unit tests. 396 friend class android::frameworks::automotive::powerpolicy::internal::CarPowerPolicyServerPeer; 397 }; 398 399 } // namespace powerpolicy 400 } // namespace automotive 401 } // namespace frameworks 402 } // namespace android 403 404 #endif // CPP_POWERPOLICY_SERVER_SRC_CARPOWERPOLICYSERVER_H_ 405