1 /*
2  * Copyright 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 #include "os/system_properties.h"
18 
19 #include <bluetooth/log.h>
20 #include <cutils/properties.h>
21 
22 #include <array>
23 #include <cctype>
24 
25 #include "common/strings.h"
26 
27 namespace bluetooth {
28 namespace os {
29 
GetSystemProperty(const std::string & property)30 std::optional<std::string> GetSystemProperty(const std::string& property) {
31   std::array<char, PROPERTY_VALUE_MAX> value_array{0};
32   auto value_len = property_get(property.c_str(), value_array.data(), nullptr);
33   if (value_len <= 0) {
34     return std::nullopt;
35   }
36   return std::string(value_array.data(), value_len);
37 }
38 
SetSystemProperty(const std::string & property,const std::string & value)39 bool SetSystemProperty(const std::string& property, const std::string& value) {
40   if (value.size() >= PROPERTY_VALUE_MAX) {
41     log::error("Property value's maximum size is {}, but {} chars were given",
42                PROPERTY_VALUE_MAX - 1, value.size());
43     return false;
44   }
45   auto ret = property_set(property.c_str(), value.c_str());
46   if (ret != 0) {
47     log::error("Set property {} failed with error code {}", property, ret);
48     return false;
49   }
50   return true;
51 }
52 
IsRootCanalEnabled()53 bool IsRootCanalEnabled() {
54   auto value = GetSystemProperty("ro.vendor.build.fingerprint");
55   if (value.has_value()) {
56     log::info("ro.vendor.build.fingerprint='{}', length={}", value->c_str(), value->length());
57   } else {
58     log::info("ro.vendor.build.fingerprint is not found");
59   }
60   // aosp_cf_x86_64_phone is just one platform that currently runs root canal
61   // When other platforms appears, or there is a better signal, add them here
62   if (value->find("generic/aosp_cf_x86_64_phone") == std::string::npos) {
63     log::info("Not on generic/aosp_cf_x86_64_phone and hence not root canal");
64     return false;
65   }
66   return true;
67 }
68 
GetAndroidVendorReleaseVersion()69 int GetAndroidVendorReleaseVersion() {
70   auto value = GetSystemProperty("ro.vendor.build.version.release_or_codename");
71   if (!value) {
72     log::info("ro.vendor.build.version.release_or_codename does not exist");
73     return 0;
74   }
75   log::info("ro.vendor.build.version.release_or_codename='{}', length={}", value->c_str(),
76             value->length());
77   auto int_value = common::Int64FromString(*value);
78   if (int_value) {
79     return static_cast<int>(*int_value);
80   }
81   log::info("value '{}' cannot be parsed to int", value->c_str());
82   if (value->empty()) {
83     log::info("value '{}' is empty", value->c_str());
84     return 0;
85   }
86   if (value->length() > 1) {
87     log::info("value '{}' length is {}, which is > 1", value->c_str(), value->length());
88   }
89   char release_code = toupper(value->at(0));
90   switch (release_code) {
91     case 'S':
92       return 11;
93     case 'R':
94       return 10;
95     case 'P':
96       return 9;
97     case 'O':
98       return 8;
99     default:
100       // Treble not enabled before Android O
101       return 0;
102   }
103 }
104 
ClearSystemPropertiesForHost()105 bool ClearSystemPropertiesForHost() { return false; }
106 
107 }  // namespace os
108 }  // namespace bluetooth
109