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