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 android_hardware_automotive_vehicle_V2_0_impl_EmulatedUserHal_H_
18 #define android_hardware_automotive_vehicle_V2_0_impl_EmulatedUserHal_H_
19 
20 #include <android-base/result.h>
21 
22 #include <android/hardware/automotive/vehicle/2.0/types.h>
23 
24 namespace android {
25 namespace hardware {
26 namespace automotive {
27 namespace vehicle {
28 namespace V2_0 {
29 
30 namespace impl {
31 
32 constexpr char kUserHalDumpOption[] = "--user-hal";
33 
34 /**
35  * Class used to emulate User HAL behavior through lshal debug requests.
36  */
37 class EmulatedUserHal {
38   public:
EmulatedUserHal()39     EmulatedUserHal() {}
40 
41     ~EmulatedUserHal() = default;
42 
43     /**
44      * Checks if the emulator can handle the property.
45      */
46     bool isSupported(int32_t prop);
47 
48     /**
49      * Lets the emulator set the property.
50      *
51      * @return updated property and StatusCode
52      */
53     android::base::Result<std::unique_ptr<VehiclePropValue>> onSetProperty(
54             const VehiclePropValue& value);
55 
56     /**
57      * Gets the property value from the emulator.
58      *
59      * @return property value and StatusCode
60      */
61     android::base::Result<std::unique_ptr<VehiclePropValue>> onGetProperty(
62             const VehiclePropValue& value);
63 
64     /**
65      * Shows the User HAL emulation help.
66      */
67     void showDumpHelp(int fd);
68 
69     /**
70      * Dump its contents.
71      */
72     void dump(int fd, std::string indent);
73 
74   private:
75     /**
76      * INITIAL_USER_INFO is called by Android when it starts, and it's expecting a property change
77      * indicating what the initial user should be.
78      *
79      * During normal circumstances, the emulator will reply right away, passing a response if
80      * InitialUserInfoResponseAction::DEFAULT (so Android could use its own logic to decide which
81      * user to boot).
82      *
83      * But during development / testing, the behavior can be changed using lshal dump, which must
84      * use the areaId to indicate what should happen next.
85      *
86      * So, the behavior of set(INITIAL_USER_INFO) is:
87      *
88      * - if it has an areaId, store the property into mInitialUserResponseFromCmd (as it was called
89      * by lshal).
90      * - else if mInitialUserResponseFromCmd is not set, return a response with the same request id
91      * and InitialUserInfoResponseAction::DEFAULT
92      * - else the behavior is defined by the areaId on mInitialUserResponseFromCmd:
93      * - if it's 1, reply with mInitialUserResponseFromCmd and the right request id
94      * - if it's 2, reply with mInitialUserResponseFromCmd but a wrong request id (so Android can
95      * test this error scenario)
96      * - if it's 3, then don't send a property change (so Android can emulate a timeout)
97      *
98      */
99     android::base::Result<std::unique_ptr<VehiclePropValue>> onSetInitialUserInfoResponse(
100             const VehiclePropValue& value);
101 
102     /**
103      * Used to emulate SWITCH_USER - see onSetInitialUserInfoResponse() for usage.
104      */
105     android::base::Result<std::unique_ptr<VehiclePropValue>> onSetSwitchUserResponse(
106             const VehiclePropValue& value);
107 
108     /**
109      * Used to emulate CREATE_USER - see onSetInitialUserInfoResponse() for usage.
110      */
111     android::base::Result<std::unique_ptr<VehiclePropValue>> onSetCreateUserResponse(
112             const VehiclePropValue& value);
113 
114     /**
115      * Used to emulate set USER_IDENTIFICATION_ASSOCIATION - see onSetInitialUserInfoResponse() for
116      * usage.
117      */
118     android::base::Result<std::unique_ptr<VehiclePropValue>> onSetUserIdentificationAssociation(
119             const VehiclePropValue& value);
120 
121     /**
122      * Used to emulate get USER_IDENTIFICATION_ASSOCIATION - see onSetInitialUserInfoResponse() for
123      * usage.
124      */
125     android::base::Result<std::unique_ptr<VehiclePropValue>> onGetUserIdentificationAssociation(
126             const VehiclePropValue& value);
127 
128     /**
129      * Creates a default USER_IDENTIFICATION_ASSOCIATION when it was not set by lshal.
130      */
131     android::base::Result<std::unique_ptr<VehiclePropValue>> defaultUserIdentificationAssociation(
132             const VehiclePropValue& request);
133 
134     android::base::Result<std::unique_ptr<VehiclePropValue>> sendUserHalResponse(
135             std::unique_ptr<VehiclePropValue> response, int32_t requestId);
136 
137     std::unique_ptr<VehiclePropValue> mInitialUserResponseFromCmd;
138     std::unique_ptr<VehiclePropValue> mSwitchUserResponseFromCmd;
139     std::unique_ptr<VehiclePropValue> mCreateUserResponseFromCmd;
140     std::unique_ptr<VehiclePropValue> mSetUserIdentificationAssociationResponseFromCmd;
141 };
142 
143 }  // namespace impl
144 
145 }  // namespace V2_0
146 }  // namespace vehicle
147 }  // namespace automotive
148 }  // namespace hardware
149 }  // namespace android
150 
151 #endif  // android_hardware_automotive_vehicle_V2_0_impl_EmulatedUserHal_H_
152