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 <android-base/result.h>
25 #include <android/frameworks/automotive/powerpolicy/BnCarPowerPolicyServer.h>
26 #include <android/frameworks/automotive/powerpolicy/internal/BnCarPowerPolicySystemNotification.h>
27 #include <android/hardware/automotive/vehicle/2.0/IVehicle.h>
28 #include <binder/IBinder.h>
29 #include <binder/Status.h>
30 #include <utils/Looper.h>
31 #include <utils/Mutex.h>
32 #include <utils/String16.h>
33 #include <utils/StrongPointer.h>
34 #include <utils/Vector.h>
35 
36 #include <optional>
37 #include <unordered_set>
38 
39 namespace android {
40 namespace frameworks {
41 namespace automotive {
42 namespace powerpolicy {
43 
44 struct CallbackInfo {
CallbackInfoCallbackInfo45     CallbackInfo(const android::sp<ICarPowerPolicyChangeCallback>& callback,
46                  const CarPowerPolicyFilter& filter, int32_t pid) :
47           callback(callback),
48           filter(filter),
49           pid(pid) {}
50 
51     android::sp<ICarPowerPolicyChangeCallback> callback;
52     CarPowerPolicyFilter filter;
53     pid_t pid;
54 };
55 
56 // Forward declaration for testing use only.
57 namespace internal {
58 
59 class CarPowerPolicyServerPeer;
60 
61 }  // namespace internal
62 
63 // Forward declaration for defining binder death handler and property change listener.
64 class CarPowerPolicyServer;
65 
66 class BinderDeathRecipient : public android::IBinder::DeathRecipient {
67 public:
68     explicit BinderDeathRecipient(const android::sp<CarPowerPolicyServer>& service);
69 
70     void binderDied(const android::wp<android::IBinder>& who) override;
71 
72 private:
73     android::sp<CarPowerPolicyServer> mService;
74 };
75 
76 class HidlDeathRecipient : public android::hardware::hidl_death_recipient {
77 public:
78     explicit HidlDeathRecipient(const android::sp<CarPowerPolicyServer>& service);
79 
80     void serviceDied(uint64_t cookie,
81                      const android::wp<android::hidl::base::V1_0::IBase>& who) override;
82 
83 private:
84     sp<CarPowerPolicyServer> mService;
85 };
86 
87 class PropertyChangeListener :
88       public android::hardware::automotive::vehicle::V2_0::IVehicleCallback {
89 public:
90     explicit PropertyChangeListener(const android::sp<CarPowerPolicyServer>& service);
91 
92     android::hardware::Return<void> onPropertyEvent(
93             const android::hardware::hidl_vec<
94                     hardware::automotive::vehicle::V2_0::VehiclePropValue>& propValues) override;
95     android::hardware::Return<void> onPropertySet(
96             const android::hardware::automotive::vehicle::V2_0::VehiclePropValue& propValue);
97     android::hardware::Return<void> onPropertySetError(
98             android::hardware::automotive::vehicle::V2_0::StatusCode status, int32_t propId,
99             int32_t areaId);
100 
101 private:
102     android::sp<CarPowerPolicyServer> mService;
103 };
104 
105 class MessageHandlerImpl : public android::MessageHandler {
106 public:
107     explicit MessageHandlerImpl(const android::sp<CarPowerPolicyServer>& service);
108 
109     void handleMessage(const android::Message& message) override;
110 
111 private:
112     android::sp<CarPowerPolicyServer> mService;
113 };
114 
115 class CarServiceNotificationHandler :
116       public android::frameworks::automotive::powerpolicy::internal::
117               BnCarPowerPolicySystemNotification {
118 public:
119     explicit CarServiceNotificationHandler(const android::sp<CarPowerPolicyServer>& server);
120 
121     android::status_t dump(int fd, const android::Vector<android::String16>& args) override;
122     android::binder::Status notifyCarServiceReady(
123             android::frameworks::automotive::powerpolicy::internal::PolicyState* policyState)
124             override;
125     android::binder::Status notifyPowerPolicyChange(const std::string& policyId,
126                                                     bool force) override;
127     android::binder::Status notifyPowerPolicyDefinition(
128             const std::string& policyId, const std::vector<std::string>& enabledComponents,
129             const std::vector<std::string>& disabledComponents) override;
130 
131 private:
132     android::sp<CarPowerPolicyServer> mService;
133 };
134 
135 /**
136  * ISilentModeChangeHandler defines a method which is called when a Silent Mode hw state is changed.
137  */
138 class ISilentModeChangeHandler {
139 public:
140     virtual ~ISilentModeChangeHandler() = 0;
141 
142     // Called when Silent Mode is changed.
143     virtual void notifySilentModeChange(const bool isSilent) = 0;
144 };
145 
146 /**
147  * CarPowerPolicyServer implements ISilentModeChangeHandler and ICarPowerPolicyServer.aidl.
148  * It handles power policy requests and Silent Mode before Android framework takes control of the
149  * device.
150  */
151 class CarPowerPolicyServer final : public ISilentModeChangeHandler, public BnCarPowerPolicyServer {
152 public:
153     static base::Result<sp<CarPowerPolicyServer>> startService(const sp<android::Looper>& looper);
154     static void terminateService();
155 
156     // Implements ICarPowerPolicyServer.aidl.
157     status_t dump(int fd, const Vector<String16>& args) override;
158     binder::Status getCurrentPowerPolicy(CarPowerPolicy* aidlReturn) override;
159     binder::Status getPowerComponentState(PowerComponent componentId, bool* aidlReturn) override;
160     binder::Status registerPowerPolicyChangeCallback(
161             const android::sp<ICarPowerPolicyChangeCallback>& callback,
162             const CarPowerPolicyFilter& filter) override;
163     binder::Status unregisterPowerPolicyChangeCallback(
164             const android::sp<ICarPowerPolicyChangeCallback>& callback) override;
165 
166     void connectToVhalHelper();
167     void handleBinderDeath(const android::wp<android::IBinder>& who);
168     void handleHidlDeath(const android::wp<android::hidl::base::V1_0::IBase>& who);
169 
170     // Implements ICarPowerPolicySystemNotification.aidl.
171     android::binder::Status notifyCarServiceReady(
172             android::frameworks::automotive::powerpolicy::internal::PolicyState* policyState);
173     android::binder::Status notifyPowerPolicyChange(const std::string& policyId, bool force);
174     android::binder::Status notifyPowerPolicyDefinition(
175             const std::string& policyId, const std::vector<std::string>& enabledComponents,
176             const std::vector<std::string>& disabledComponents);
177 
178     /**
179      * Applies the given power policy.
180      *
181      * @param carServiceInOperation expected Car Service running state.
182      * @param force whether to apply the policy even when the current policy is a system
183      *        power policy.
184      */
185     android::base::Result<void> applyPowerPolicy(const std::string& policyId,
186                                                  const bool carServiceInOperation,
187                                                  const bool force);
188     /**
189      * Sets the power policy group which contains rules to map a power state to a default power
190      * policy to apply.
191      */
192     android::base::Result<void> setPowerPolicyGroup(const std::string& groupId);
193 
194     // Implements ISilentModeChangeHandler.
195     void notifySilentModeChange(const bool isSilent);
196 
197 private:
198     CarPowerPolicyServer();
199 
200     android::base::Result<void> init(const android::sp<android::Looper>& looper);
201     void terminate();
202     bool isRegisteredLocked(const android::sp<ICarPowerPolicyChangeCallback>& callback);
203     void connectToVhal();
204     void applyInitialPowerPolicy();
205     void subscribeToVhal();
206     void subscribeToProperty(
207             int32_t prop,
208             std::function<
209                     void(const android::hardware::automotive::vehicle::V2_0::VehiclePropValue&)>
210                     processor);
211     android::base::Result<void> notifyVhalNewPowerPolicy(const std::string& policyId);
212     bool isPropertySupported(const int32_t prop);
213     bool isPowerPolicyAppliedLocked() const;
214 
215 private:
216     static android::sp<CarPowerPolicyServer> sCarPowerPolicyServer;
217 
218     sp<android::Looper> mHandlerLooper;
219     sp<MessageHandlerImpl> mMessageHandler;
220     PowerComponentHandler mComponentHandler;
221     PolicyManager mPolicyManager;
222     SilentModeHandler mSilentModeHandler;
223     android::Mutex mMutex;
224     CarPowerPolicyMeta mCurrentPowerPolicyMeta GUARDED_BY(mMutex);
225     std::string mCurrentPolicyGroupId GUARDED_BY(mMutex);
226     std::string mPendingPowerPolicyId GUARDED_BY(mMutex);
227     bool mIsPowerPolicyLocked GUARDED_BY(mMutex);
228     std::vector<CallbackInfo> mPolicyChangeCallbacks GUARDED_BY(mMutex);
229     android::sp<android::hardware::automotive::vehicle::V2_0::IVehicle> mVhalService
230             GUARDED_BY(mMutex);
231     std::optional<int64_t> mLastApplyPowerPolicyUptimeMs GUARDED_BY(mMutex);
232     std::optional<int64_t> mLastSetDefaultPowerPolicyGroupUptimeMs GUARDED_BY(mMutex);
233     bool mIsCarServiceInOperation GUARDED_BY(mMutex);
234     // No thread-safety guard is needed because only accessed through main thread handler.
235     bool mIsFirstConnectionToVhal;
236     std::unordered_map<int32_t, bool> mSupportedProperties;
237     android::sp<BinderDeathRecipient> mBinderDeathRecipient;
238     android::sp<HidlDeathRecipient> mHidlDeathRecipient;
239     android::sp<PropertyChangeListener> mPropertyChangeListener;
240     android::sp<CarServiceNotificationHandler> mCarServiceNotificationHandler;
241     int32_t mRemainingConnectionRetryCount;
242 
243     // For unit tests.
244     friend class android::frameworks::automotive::powerpolicy::internal::CarPowerPolicyServerPeer;
245 };
246 
247 }  // namespace powerpolicy
248 }  // namespace automotive
249 }  // namespace frameworks
250 }  // namespace android
251 
252 #endif  // CPP_POWERPOLICY_SERVER_SRC_CARPOWERPOLICYSERVER_H_
253