• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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