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 #include <inttypes.h>
18 #include <sys/utsname.h>
19 
20 #include <android-base/stringprintf.h>
21 #include <android-base/logging.h>
22 #include <kver/kernel_release.h>
23 #include <kver/utils.h>
24 
25 namespace android::kver {
26 
27 bool IsKernelUpdateValid(const std::optional<KernelRelease>& old_kernel_release,
28                          const std::optional<KernelRelease>& new_kernel_release) {
29   // Allow update from non-GKI to non-GKI for legacy devices, or non-GKI to GKI for retrofit
30   // devices.
31   if (!old_kernel_release.has_value()) {
32     LOG(INFO) << "Current build does not contain GKI, permit update to \""
33               << (new_kernel_release.has_value() ? new_kernel_release->string() : "")
34               << "\" anyways.";
35     return true;
36   }
37 
38   if (!new_kernel_release.has_value()) {
39     LOG(ERROR) << "Cannot update from GKI \"" << old_kernel_release->string()
40                << "\" to non-GKI build.";
41     return false;
42   }
43 
44   // Check that KMI version does not downgrade; i.e. the tuple(w, x, z, k) does
45   // not decrease.
46   if (old_kernel_release->kmi_version().tuple() > new_kernel_release->kmi_version().tuple()) {
47     LOG(ERROR) << "Cannot update from " << old_kernel_release->string() << " to "
48                << new_kernel_release->string() << ": KMI version decreases.";
49     return false;
50   }
51 
52   // This ensures that Android release does not downgrade, e.g. you cannot go
53   // from 5.10-android13-0 to 5.15-android12-0.
54   if (old_kernel_release->android_release() > new_kernel_release->android_release()) {
55     LOG(ERROR) << "Cannot update from " << old_kernel_release->string() << " to "
56                << new_kernel_release->string() << ": Android release decreases.";
57     return false;
58   }
59 
60   // This ensures that w.x.y does not downgrade; e.g. you cannot go
61   // from 5.4.43 to 5.4.42, but you can go from 5.4.43 to 5.10.5.
62   if (old_kernel_release->kernel_version_tuple() > new_kernel_release->kernel_version_tuple()) {
63     LOG(ERROR) << "Cannot update from " << old_kernel_release->string() << " to "
64                << new_kernel_release->string() << ": Kernel version decreases.";
65     return false;
66   }
67 
68   LOG(INFO) << "Allow to update from " << old_kernel_release->string() << " to "
69             << new_kernel_release->string();
70   return true;
71 }
72 
73 // Keep in sync with kmi.go.
74 std::string GetApexName(const KmiVersion& kmi_version) {
75   static constexpr const char* KMI_VERSION_APEX_NAME_FORMAT{
76       "com.android.gki.kmi_%" PRIu64 "_%" PRIu64 "_android%" PRIu64 "_%" PRIu64};
77   return android::base::StringPrintf(KMI_VERSION_APEX_NAME_FORMAT, kmi_version.version(), kmi_version.patch_level(),
78                                      kmi_version.android_release(), kmi_version.generation());
79 }
80 
81 uint64_t GetFactoryApexVersion() {
82   return 300000000;
83 }
84 
85 }  // namespace android::kver
86