diff --git a/apex/sdkext/Android.bp b/apex/sdkext/Android.bp index b8dcb90057d2c..12d6b8687eb1d 100644 --- a/apex/sdkext/Android.bp +++ b/apex/sdkext/Android.bp @@ -15,7 +15,9 @@ apex { name: "com.android.sdkext", manifest: "manifest.json", + binaries: [ "derive_sdk" ], java_libs: [ "framework-sdkext" ], + prebuilts: [ "com.android.sdkext.ldconfig" ], key: "com.android.sdkext.key", certificate: ":com.android.sdkext.certificate", } @@ -30,3 +32,10 @@ android_app_certificate { name: "com.android.sdkext.certificate", certificate: "com.android.sdkext", } + +prebuilt_etc { + name: "com.android.sdkext.ldconfig", + src: "ld.config.txt", + filename: "ld.config.txt", + installable: false, +} diff --git a/apex/sdkext/derive_sdk/Android.bp b/apex/sdkext/derive_sdk/Android.bp new file mode 100644 index 0000000000000..39f1943bfa790 --- /dev/null +++ b/apex/sdkext/derive_sdk/Android.bp @@ -0,0 +1,31 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +cc_binary { + name: "derive_sdk", + srcs: [ + "derive_sdk.cpp", + "sdk.proto", + ], + proto: { + type: "lite", + }, + sdk_version: "current", + stl: "c++_static", + shared_libs: [ "liblog" ], + static_libs: [ + "libbase_ndk", + "libprotobuf-cpp-lite-ndk", + ], +} diff --git a/apex/sdkext/derive_sdk/derive_sdk.cpp b/apex/sdkext/derive_sdk/derive_sdk.cpp new file mode 100644 index 0000000000000..0aacebefaacad --- /dev/null +++ b/apex/sdkext/derive_sdk/derive_sdk.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "derive_sdk" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "frameworks/base/apex/sdkext/derive_sdk/sdk.pb.h" + +using com::android::sdkext::proto::SdkVersion; + +int main(int, char**) { + std::unique_ptr apex(opendir("/apex"), closedir); + if (!apex) { + LOG(ERROR) << "Could not read /apex"; + return EXIT_FAILURE; + } + struct dirent* de; + std::vector paths; + while ((de = readdir(apex.get()))) { + std::string name = de->d_name; + if (name[0] == '.' || name.find('@') != std::string::npos) { + // Skip @ dirs, as they are bind-mounted to + continue; + } + std::string path = "/apex/" + name + "/etc/sdkinfo.binarypb"; + struct stat statbuf; + if (stat(path.c_str(), &statbuf) == 0) { + paths.push_back(path); + } + } + + std::vector versions; + for (const auto& path : paths) { + std::string contents; + if (!android::base::ReadFileToString(path, &contents, true)) { + LOG(ERROR) << "failed to read " << path; + continue; + } + SdkVersion sdk_version; + if (!sdk_version.ParseFromString(contents)) { + LOG(ERROR) << "failed to parse " << path; + continue; + } + versions.push_back(sdk_version.version()); + } + auto itr = std::min_element(versions.begin(), versions.end()); + std::string prop_value = itr == versions.end() ? "0" : std::to_string(*itr); + + if (!android::base::SetProperty("persist.com.android.sdkext.sdk_info", prop_value)) { + LOG(ERROR) << "failed to set sdk_info prop"; + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/apex/sdkext/derive_sdk/sdk.proto b/apex/sdkext/derive_sdk/sdk.proto new file mode 100644 index 0000000000000..d15b93552ff4c --- /dev/null +++ b/apex/sdkext/derive_sdk/sdk.proto @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +syntax = "proto3"; +package com.android.sdkext.proto; + +option java_outer_classname = "SdkProto"; +option optimize_for = LITE_RUNTIME; + +message SdkVersion { + int32 version = 1; +} diff --git a/apex/sdkext/ld.config.txt b/apex/sdkext/ld.config.txt new file mode 100644 index 0000000000000..b4470685f4fc4 --- /dev/null +++ b/apex/sdkext/ld.config.txt @@ -0,0 +1,31 @@ +# Copyright (C) 2019 The Android Open Source Project +# +# Bionic loader config file for the sdkext apex. + +dir.sdkext = /apex/com.android.sdkext/bin/ + +[sdkext] +additional.namespaces = platform + +namespace.default.isolated = true +namespace.default.links = platform +namespace.default.link.platform.allow_all_shared_libs = true + +############################################################################### +# "platform" namespace: used for NDK libraries +############################################################################### +namespace.platform.isolated = true +namespace.platform.search.paths = /system/${LIB} +namespace.platform.asan.search.paths = /data/asan/system/${LIB} + +# /system/lib/libc.so, etc are symlinks to /apex/com.android.lib/lib/bionic/libc.so, etc. +# Add /apex/... path to the permitted paths because linker uses realpath(3) +# to check the accessibility of the lib. We could add this to search.paths +# instead but that makes the resolution of bionic libs be dependent on +# the order of /system/lib and /apex/... in search.paths. If /apex/... +# is after /system/lib, then /apex/... is never tried because libc.so +# is always found in /system/lib but fails to pass the accessibility test +# because of its realpath. It's better to not depend on the ordering if +# possible. +namespace.platform.permitted.paths = /apex/com.android.runtime/${LIB}/bionic +namespace.platform.asan.permitted.paths = /apex/com.android.runtime/${LIB}/bionic