1 /*
2  * Copyright (C) 2019 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 #pragma once
18 
19 #include <stddef.h>
20 #include <stdint.h>
21 
22 #include <optional>
23 #include <string>
24 
25 namespace android {
26 namespace hardware {
27 namespace google {
28 namespace pixel {
29 
30 enum class MiscWriterActions : int32_t {
31   kSetDarkThemeFlag = 0,
32   kClearDarkThemeFlag,
33   kSetSotaFlag,
34   kClearSotaFlag,
35   kSetEnablePkvmFlag,
36   kSetDisablePkvmFlag,
37   kSetWristOrientationFlag,
38   kClearWristOrientationFlag,
39   kWriteTimeFormat,
40   kWriteTimeOffset,
41   kSetMaxRamSize,
42   kClearMaxRamSize,
43   kWriteTimeRtcOffset,
44   kWriteTimeMinRtc,
45   kSetSotaConfig,
46   kWriteDstTransition,
47   kWriteDstOffset,
48   kSetDisplayMode,
49   kClearDisplayMode,
50   kWriteEagleEyePatterns,
51   kSetDisableFaceauthEval,
52   kClearDisableFaceauthEval,
53 
54   kUnset = -1,
55 };
56 
57 class MiscWriter {
58   public:
59     // sync with bootloader's abl bootloader_message.h
60     typedef struct bootloader_message_vendor {
61         char theme[32];
62         char sota[32];
63         char pkvm[32];
64         char wrist_orientation[32];
65         char timeformat[32];
66         char timeoffset[32];
67         char max_ram_size[32];
68         char sota_client_state[40];
69         char timertcoffset[32];
70         char timeminrtc[32];
71         char faceauth_eval[32];
72         char sota_schedule_shipmode[32];
73         char dsttransition[32];
74         char dstoffset[32];
75         char user_preferred_resolution[32];
76         char sota_csku[8];
77         char sota_csku_signature[96];
78         char eagleEye[32];
79         char skipUnbootableCheck[32];
80     } __attribute__((__packed__)) bootloader_message_vendor_t;
81 
82     static constexpr uint32_t kThemeFlagOffsetInVendorSpace =
83             offsetof(bootloader_message_vendor_t, theme);
84     static constexpr char kDarkThemeFlag[] = "theme-dark";
85     static constexpr uint32_t kSotaFlagOffsetInVendorSpace =
86             offsetof(bootloader_message_vendor_t, sota);
87     static constexpr char kSotaFlag[] = "enable-sota";
88     static constexpr uint32_t kPkvmFlagOffsetInVendorSpace =
89             offsetof(bootloader_message_vendor_t, pkvm);
90     static constexpr char kEnablePkvmFlag[] = "enable-pkvm";
91     static constexpr char kDisablePkvmFlag[] = "disable-pkvm";
92     static constexpr uint32_t kWristOrientationFlagOffsetInVendorSpace =
93             offsetof(bootloader_message_vendor_t, wrist_orientation);
94     static constexpr char kWristOrientationFlag[] = "wrist-orientation=";
95     static constexpr uint32_t kTimeFormatValOffsetInVendorSpace =
96             offsetof(bootloader_message_vendor_t, timeformat);
97     static constexpr char kTimeFormat[] = "timeformat=";
98     static constexpr uint32_t kTimeOffsetValOffsetInVendorSpace =
99             offsetof(bootloader_message_vendor_t, timeoffset);
100     static constexpr char kTimeOffset[] = "timeoffset=";
101     static constexpr uint32_t kMaxRamSizeOffsetInVendorSpace =
102             offsetof(bootloader_message_vendor_t, max_ram_size);
103     static constexpr char kMaxRamSize[] = "max-ram-size=";
104     static constexpr uint32_t kSotaStateOffsetInVendorSpace =
105             offsetof(bootloader_message_vendor_t, sota_client_state);
106     static constexpr uint32_t kRTimeRtcOffsetValOffsetInVendorSpace =
107             offsetof(bootloader_message_vendor_t, timertcoffset);
108     static constexpr char kTimeRtcOffset[] = "timertcoffset=";
109     static constexpr uint32_t kRTimeMinRtcValOffsetInVendorSpace =
110             offsetof(bootloader_message_vendor_t, timeminrtc);
111     static constexpr char kTimeMinRtc[] = "timeminrtc=";
112     static constexpr uint32_t kFaceauthEvalValOffsetInVendorSpace =
113             offsetof(bootloader_message_vendor_t, faceauth_eval);
114     static constexpr char kDisableFaceauthEvalFlag[] = "disable-faceauth-eval";
115     static constexpr uint32_t kSotaScheduleShipmodeOffsetInVendorSpace =
116             offsetof(bootloader_message_vendor_t, sota_schedule_shipmode);
117     static constexpr uint32_t kDstTransitionOffsetInVendorSpace =
118             offsetof(bootloader_message_vendor_t, dsttransition);
119     static constexpr char kDstTransition[] = "dst-transition=";
120     static constexpr uint32_t kDstOffsetOffsetInVendorSpace =
121             offsetof(bootloader_message_vendor_t, dstoffset);
122     static constexpr char kDstOffset[] = "dst-offset=";
123     static constexpr uint32_t kDisplayModeOffsetInVendorSpace =
124             offsetof(bootloader_message_vendor_t, user_preferred_resolution);
125     static constexpr char kDisplayModePrefix[] = "mode=";
126     static constexpr uint32_t kEagleEyeOffset =
127             offsetof(bootloader_message_vendor_t, eagleEye);
128 
129     // Minimum and maximum valid value for max-ram-size
130     static constexpr int32_t kRamSizeDefault = -1;
131     static constexpr uint32_t kRamSizeMin = 2048;
132     static constexpr uint32_t kRamSizeMax = 65536;
133 
134     // Minimum and maximum time zone are -12 and 14 hours from GMT
135     static constexpr int32_t kMinTimeOffset = -12 * 60 * 60 * 1000;
136     static constexpr int32_t kMaxTimeOffset = 14 * 60 * 60 * 1000;
137 
138     // Maximum display mode string length
139     static constexpr size_t kDisplayModeMaxSize = 32 - sizeof(kDisplayModePrefix);
140 
141     // Returns true of |size| bytes data starting from |offset| is fully inside the vendor space.
142     static bool OffsetAndSizeInVendorSpace(size_t offset, size_t size);
143     // Writes the given data to the vendor space in /misc partition, at the given offset. Note that
144     // offset is in relative to the start of the vendor space.
145     static bool WriteMiscPartitionVendorSpace(const void *data, size_t size, size_t offset,
146                                               std::string *err);
147 
MiscWriter(const MiscWriterActions & action)148     explicit MiscWriter(const MiscWriterActions &action) : action_(action) {}
MiscWriter(const MiscWriterActions & action,const char data)149     explicit MiscWriter(const MiscWriterActions &action, const char data)
150         : action_(action), chardata_(data) {}
MiscWriter(const MiscWriterActions & action,std::string data)151     explicit MiscWriter(const MiscWriterActions &action, std::string data)
152         : action_(action), stringdata_(data) {}
153 
154     // Performs the stored MiscWriterActions. If |override_offset| is set, writes to the input
155     // offset in the vendor space of /misc instead of the default offset.
156     bool PerformAction(std::optional<size_t> override_offset = std::nullopt);
157     bool UpdateSotaConfig(std::optional<size_t> override_offset = std::nullopt);
158 
159   private:
160     MiscWriterActions action_{MiscWriterActions::kUnset};
161     char chardata_{'0'};
162     std::string stringdata_;
163 };
164 
165 }  // namespace pixel
166 }  // namespace google
167 }  // namespace hardware
168 }  // namespace android
169