1 /* Copyright 2020 The TensorFlow Authors. All Rights Reserved. 2 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 7 http://www.apache.org/licenses/LICENSE-2.0 8 9 Unless required by applicable law or agreed to in writing, software 10 distributed under the License is distributed on an "AS IS" BASIS, 11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 See the License for the specific language governing permissions and 13 limitations under the License. 14 ==============================================================================*/ 15 #include "tensorflow/lite/experimental/acceleration/compatibility/android_info.h" 16 17 #include <iostream> 18 #include <string> 19 20 #include "absl/status/status.h" 21 22 #ifdef __ANDROID__ 23 #include <sys/system_properties.h> 24 #endif // __ANDROID__ 25 26 namespace { GetPropertyValue(const std::string & property)27std::string GetPropertyValue(const std::string& property) { 28 #ifdef __ANDROID__ 29 char value[PROP_VALUE_MAX]; 30 __system_property_get(property.c_str(), value); 31 return std::string(value); 32 #else // !__ANDROID__ 33 return std::string(); 34 #endif // __ANDROID__ 35 } 36 } // namespace 37 38 namespace tflite { 39 namespace acceleration { 40 RequestAndroidInfo(AndroidInfo * info_out)41absl::Status RequestAndroidInfo(AndroidInfo* info_out) { 42 if (!info_out) { 43 return absl::InvalidArgumentError("info_out may not be null"); 44 } 45 info_out->android_sdk_version = GetPropertyValue("ro.build.version.sdk"); 46 info_out->device = GetPropertyValue("ro.product.device"); 47 info_out->model = GetPropertyValue("ro.product.model"); 48 info_out->manufacturer = GetPropertyValue("ro.product.manufacturer"); 49 #ifdef __ANDROID__ 50 // Based on 51 // https://github.com/flutter/plugins/blob/master/packages/device_info/device_info/android/src/main/java/io/flutter/plugins/deviceinfo/MethodCallHandlerImpl.java 52 // + QUMA detection (system properties return empty) and qemu detection 53 // (ro.kernel.qemu). 54 std::string brand = GetPropertyValue("ro.product.brand"); 55 const std::string& device = info_out->device; 56 std::string fingerprint = GetPropertyValue("ro.build.fingerprint"); 57 std::string hardware = GetPropertyValue("ro.hardware"); 58 const std::string& model = info_out->model; 59 const std::string& manufacturer = info_out->manufacturer; 60 std::string product = GetPropertyValue("ro.build.product"); 61 std::string ro_kernel_qemu = GetPropertyValue("ro.kernel.qemu"); 62 info_out->is_emulator = 63 ((brand.find("generic") == 0 && device.find("generic") == 0) || // NOLINT 64 fingerprint.find("generic") == 0 || // NOLINT 65 fingerprint.find("unknown") == 0 || // NOLINT 66 hardware.find("goldfish") != std::string::npos || // NOLINT 67 hardware.find("ranchu") != std::string::npos || // NOLINT 68 model.find("google_sdk") != std::string::npos || // NOLINT 69 model.find("Emulator") != std::string::npos || // NOLINT 70 model.find("Android SDK built for x86") != // NOLINT 71 std::string::npos || // NOLINT 72 manufacturer.find("Genymotion") != std::string::npos || // NOLINT 73 product.find("sdk_google") != std::string::npos || // NOLINT 74 product.find("google_sdk") != std::string::npos || // NOLINT 75 product.find("sdk") != std::string::npos || // NOLINT 76 product.find("sdk_x86") != std::string::npos || // NOLINT 77 product.find("vbox86p") != std::string::npos || // NOLINT 78 product.find("emulator") != std::string::npos || // NOLINT 79 product.find("simulator") != std::string::npos || // NOLINT 80 ro_kernel_qemu == "1" || // NOLINT 81 info_out->android_sdk_version.empty()); // NOLINT 82 #else 83 info_out->is_emulator = false; 84 #endif 85 86 return absl::OkStatus(); 87 } 88 89 } // namespace acceleration 90 } // namespace tflite 91