Sistem özellikleri, genellikle bilgi paylaşımı için uygun bir yol sunar.
yapılandırmalarına yardımcı olur. Her bölüm kendi sistem özelliklerini kullanabilir
içten içe. Mülklere bölümler arasında erişildiğinde (ör. /vendor
tarafından tanımlanan mülklere /system
tarafından erişilmesi) bir sorun oluşabilir. Android 8.0'dan beri
/system
gibi bazı bölümler yükseltilebilir, ancak /vendor
kaldı
değişmedi. Sistem özellikleri yalnızca dizenin genel bir sözlüğü olduğundan
anahtar/değer çiftleri içeriyorsa özelliklerin dengelenmesi zordur. İlgili içeriği oluşturmak için kullanılan
/system
bölümü, /vendor
öğesinin etkinleştirebileceği özellikleri değiştirebilir veya kaldırabilir
bağlı olarak değişiklik gösterebilir.
Android 10 sürümünden itibaren, bölümler arasında erişilen sistem özellikleri Sysprop Description dosyalarında şematize edilir ve özelliklere erişmek için API'ler C++ ve Rust için somut işlevler, Java için sınıflar olarak oluşturulur. Herhangi bir sihirbazlık olanağı olmadığı için bu API'lerin kullanımı daha kolaydır.
dizeler (ro.build.date
gibi) erişim için gereklidir ve
otomatik olarak yazılır. Derleme sırasında ABI kararlılığı da kontrol edilir ve
çalışmaya devam edebilir. Bu kontrol, açıkça tanımlanmış şekilde çalışır
nasıl yapılandıracağınızı kontrol edin. Bu API'ler, aynı zamanda
Rust, Java ve C++.
Sistem özelliklerini API olarak tanımlama
Sistem özelliklerini, aşağıdaki şemayı kullanan protobuf TextFormat'ı kullanan Sysprop Description dosyaları (.sysprop
) ile API olarak tanımlayın:
// File: sysprop.proto
syntax = "proto3";
package sysprop;
enum Access {
Readonly = 0;
Writeonce = 1;
ReadWrite = 2;
}
enum Owner {
Platform = 0;
Vendor = 1;
Odm = 2;
}
enum Scope {
Public = 0;
Internal = 2;
}
enum Type {
Boolean = 0;
Integer = 1;
Long = 2;
Double = 3;
String = 4;
Enum = 5;
UInt = 6;
ULong = 7;
BooleanList = 20;
IntegerList = 21;
LongList = 22;
DoubleList = 23;
StringList = 24;
EnumList = 25;
UIntList = 26;
ULongList = 27;
}
message Property {
string api_name = 1;
Type type = 2;
Access access = 3;
Scope scope = 4;
string prop_name = 5;
string enum_values = 6;
bool integer_as_bool = 7;
string legacy_prop_name = 8;
}
message Properties {
Owner owner = 1;
string module = 2;
repeated Property prop = 3;
}
Bir Sysprop Açıklama dosyası, grubudur. Alanlarının anlamı aşağıdaki gibidir.
Alan | Anlamı |
---|---|
owner
|
Şu mülklerin sahibi olan bölüm olarak ayarlandı: Platform ,
Vendor veya Odm .
|
module
|
İçinde bulunduğunuz adın kullanıldığı bir ad alanı (C++) veya statik son sınıf (Java) oluşturmak için kullanılır.
oluşturulan API'lerin
yerleştirilmesine yardımcı olur. Örneğin,
com.android.sysprop.BuildProperties
C++'ta com::android::sysprop::BuildProperties ad alanı olacaktır
ve paketteki BuildProperties sınıfını
Java'da com.android.sysprop .
|
prop
|
Tesis listesi. |
Property
mesaj alanlarının anlamları aşağıda verilmiştir.
Alan | Anlamı |
---|---|
api_name
|
Oluşturulan API'nin adı. |
type
|
Bu mülkün türü. |
access
|
Readonly : Yalnızca getter API oluşturur
Writeonce , ReadWrite : Alıcı ve belirleyici API'ler oluşturur
Not: ro. ön ekine sahip mülkler,
ReadWrite erişim.
|
scope
|
Internal : Yalnızca sahibi erişebilir.
Public : NDK modülleri dışında herkes erişebilir.
|
prop_name
|
Temel sistem özelliğinin adı. Örneğin,
ro.build.date
|
enum_values
|
(Enum , yalnızca EnumList ) Çubuk(|) ile ayrılmış bir dize
olası enum değerlerinden oluşur. Örneğin, value1|value2 .
|
integer_as_bool
|
(Yalnızca Boolean , BooleanList ) Setterleri kullan
false ve yerine 0 ve 1
true .
|
legacy_prop_name
|
(isteğe bağlı, yalnızca Readonly mülkleri) Etiketin eski adı
temel sistem özelliğini kullanabilirsiniz. Alıcıyı çağırırken alıcı API'si
prop_name ve aşağıdaki durumlarda legacy_prop_name kullanır
prop_name mevcut değil. Şu durumlarda legacy_prop_name kullanın:
mevcut bir mülkü kullanımdan kaldırıp yeni bir mülke taşıma
|
Her özellik türü, C++, Java ve Rust'ta aşağıdaki türlerle eşlenir.
Tür | C++ | Java | Rust |
---|---|---|---|
Boole | std::optional<bool>
|
Optional<Boolean>
|
bool
|
Tam sayı | std::optional<std::int32_t>
|
Optional<Integer>
|
i32
|
Kullanıcı arayüzü | std::optional<std::uint32_t>
|
Optional<Integer>
|
u32
|
Uzun | std::optional<std::int64_t>
|
Optional<Long>
|
i64
|
ULong | std::optional<std::uint64_t>
|
Optional<Long>
|
u64
|
Çift | std::optional<double>
|
Optional<Double>
|
f64
|
Dize | std::optional<std::string>
|
Optional<String>
|
String
|
Enum | std::optional<{api_name}_values>
|
Optional<{api_name}_values>
|
{ApiName}Values
|
T Listesi | std::vector<std::optional<T>>
|
List<T>
|
Vec<T>
|
Burada, üç özelliği tanımlayan bir Sysprop Açıklama dosyası örneğini bulabilirsiniz:
# File: android/sysprop/PlatformProperties.sysprop
owner: Platform
module: "android.sysprop.PlatformProperties"
prop {
api_name: "build_date"
type: String
prop_name: "ro.build.date"
scope: Public
access: Readonly
}
prop {
api_name: "date_utc"
type: Integer
prop_name: "ro.build.date_utc"
scope: Internal
access: Readonly
}
prop {
api_name: "device_status"
type: Enum
enum_values: "on|off|unknown"
prop_name: "device.status"
scope: Public
access: ReadWrite
}
Sistem özelliği kitaplıklarını tanımlama
Artık Sysprop Açıklama dosyalarıyla sysprop_library
modül tanımlayabilirsiniz.
sysprop_library
; C++, Java ve Rust için bir API işlevi görür. Derleme sistemi
dahili olarak bir rust_library
, bir java_library
ve bir cc_library
oluşturur
her sysprop_library
örneği için geçerlidir.
// File: Android.bp
sysprop_library {
name: "PlatformProperties",
srcs: ["android/sysprop/PlatformProperties.sysprop"],
property_owner: "Platform",
vendor_available: true,
}
API kontrolleri için kaynağa API listesi dosyaları eklemeniz gerekir. Bunu yapmak için
API dosyaları ve api
dizini oluşturabilirsiniz. api
dizinini aynı klasöre koyun
Android.bp
olarak dizin. API dosya adları <module_name>-current.txt
,
<module_name>-latest.txt
. API imzalarını <module_name>-current.txt
barındırır
güncel kaynak kodundan oluşur ve <module_name>-latest.txt
dondurulmuş en son kodu barındırır
API imzaları. Derleme sistemi API'lerin
bu API dosyalarını, derleme sırasında oluşturulan API dosyalarıyla karşılaştırır ve
current.txt
durumunda hata mesajı ve current.txt
dosyasını güncelleme talimatları
kaynak kodlarıyla eşleşmiyor. Burada, örnek bir dizin ve dosya
kuruluş:
├── api
│ ├── PlatformProperties-current.txt
│ └── PlatformProperties-latest.txt
└── Android.bp
Rust, Java ve C++ istemci modülleri, sysprop_library
ile bağlantı kurarak
API'lerden yararlanıldı. Derleme sistemi, istemcilerden oluşturulan C++, Java ve Rust kitaplıklarına bağlantılar oluşturur. Böylece istemcilere oluşturulan API'lere erişim izni verir.
java_library {
name: "JavaClient",
srcs: ["foo/bar.java"],
libs: ["PlatformProperties"],
}
cc_binary {
name: "cc_client",
srcs: ["baz.cpp"],
shared_libs: ["PlatformProperties"],
}
rust_binary {
name: "rust_client",
srcs: ["src/main.rs"],
rustlibs: ["libplatformproperties_rust"],
}
Rust kitaplığı adının, sysprop_library
dönüştürülerek oluşturulduğunu unutmayın
önce .
ve -
yerine _
, sonra da başa lib
ve
_rust
ekleniyor.
Yukarıdaki örnekte, tanımlanan özelliklere aşağıdaki gibi erişebilirsiniz.
Pas örneği:
use platformproperties::DeviceStatusValues;
fn foo() -> Result<(), Error> {
// Read "ro.build.date_utc". default value is -1.
let date_utc = platformproperties::date_utc()?.unwrap_or_else(-1);
// set "device.status" to "unknown" if "ro.build.date" is not set.
if platformproperties::build_date()?.is_none() {
platformproperties::set_device_status(DeviceStatusValues::UNKNOWN);
}
…
}
Java örneği:
import android.sysprop.PlatformProperties;
…
static void foo() {
…
// read "ro.build.date_utc". default value is -1
Integer dateUtc = PlatformProperties.date_utc().orElse(-1);
// set "device.status" to "unknown" if "ro.build.date" is not set
if (!PlatformProperties.build_date().isPresent()) {
PlatformProperties.device_status(
PlatformProperties.device_status_values.UNKNOWN
);
}
…
}
…
C++ örneği:
#include <android/sysprop/PlatformProperties.sysprop.h>
using namespace android::sysprop;
…
void bar() {
…
// read "ro.build.date". default value is "(unknown)"
std::string build_date = PlatformProperties::build_date().value_or("(unknown)");
// set "device.status" to "on" if it's "unknown" or not set
using PlatformProperties::device_status_values;
auto status = PlatformProperties::device_status();
if (!status.has_value() || status.value() == device_status_values::UNKNOWN) {
PlatformProperties::device_status(device_status_values::ON);
}
…
}
…