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