सिस्टम प्रॉपर्टी, जानकारी, आम तौर पर कॉन्फ़िगरेशन, पूरे सिस्टम पर शेयर करने का एक आसान तरीका देती हैं. हर पार्टीशन, इंटरनल तौर पर अपनी सिस्टम प्रॉपर्टी
का इस्तेमाल कर सकता है. जब प्रॉपर्टी को सभी सेगमेंट में ऐक्सेस किया जाता है, तब समस्या हो सकती है, जैसे कि /vendor
, /system
की तय की गई प्रॉपर्टी को ऐक्सेस करता है. Android 8.0 के बाद से,
/system
जैसे कुछ पार्टिशन, अपग्रेड किए जा सकते हैं, जबकि /vendor
में कोई बदलाव
नहीं होगा. सिस्टम प्रॉपर्टी, बिना स्कीमा वाले स्ट्रिंग की-वैल्यू पेयर की ग्लोबल डिक्शनरी हैं. इसलिए, प्रॉपर्टी को स्थिर करना मुश्किल है. /system
पार्टीशन, उन प्रॉपर्टी को बदल या हटा सकता है जिन पर /vendor
पार्टीशन बिना किसी सूचना के निर्भर करता है.
Android 10 की रिलीज़ के बाद से, सभी पार्टिशन में ऐक्सेस की गई सिस्टम प्रॉपर्टी को Sysprop की जानकारी वाली फ़ाइलों में स्कीमा दिया जाता है. साथ ही, प्रॉपर्टी को ऐक्सेस करने के लिए, C++ और Rust के लिए कंक्रीट फ़ंक्शन के तौर पर, और Java की क्लास को जनरेट किया जाता है. इन एपीआई का इस्तेमाल करना ज़्यादा आसान है, क्योंकि ऐक्सेस के लिए किसी मैजिक स्ट्रिंग (जैसे कि ro.build.date
) की ज़रूरत नहीं होती. साथ ही, इन्हें स्टैटिक टाइप किया जा सकता है. बिल्ड के समय भी एबीआई की स्थिरता की जांच की जाती है और साथ काम न करने वाले बदलाव होने पर बिल्ड रुक जाता है. यह जांच, सेगमेंट के बीच साफ़ तौर पर तय
इंटरफ़ेस की तरह काम करती है. ये एपीआई, रस्ट, Java, और C++ के बीच
एक जैसा अनुभव भी दे सकते हैं.
सिस्टम की प्रॉपर्टी को एपीआई के तौर पर परिभाषित करें
सिस्टम की प्रॉपर्टी को Sysprop के बारे में जानकारी देने वाली फ़ाइलों (.sysprop
) के साथ एपीआई के तौर पर परिभाषित करें. ये फ़ाइलें, इस स्कीमा के साथ प्रोटोबफ़ के TextFormat का इस्तेमाल करती हैं:
// 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;
}
एक Sysop विवरण फ़ाइल में एक प्रॉपर्टी मैसेज होता है, जो प्रॉपर्टी के एक सेट के बारे में बताता है. इसके फ़ील्ड के मतलब यहां दिए गए हैं.
फ़ील्ड | मतलब |
---|---|
owner
|
उस सेगमेंट पर सेट करें जिसके पास प्रॉपर्टी का मालिकाना हक है: Platform ,
Vendor या Odm .
|
module
|
इसका इस्तेमाल नेमस्पेस (C++) या स्टैटिक फ़ाइनल क्लास (Java) बनाने के लिए किया जाता है, जिनमें जनरेट किए गए एपीआई रखे जाते हैं. उदाहरण के लिए, C++ में com.android.sysprop.BuildProperties नेमस्पेस com::android::sysprop::BuildProperties और Java में com.android.sysprop के पैकेज में BuildProperties क्लास होगी.
|
prop
|
प्रॉपर्टी की सूची. |
Property
मैसेज फ़ील्ड का मतलब यहां बताया गया है.
फ़ील्ड | मतलब |
---|---|
api_name
|
जनरेट किए गए एपीआई का नाम. |
type
|
इस प्रॉपर्टी का टाइप. |
access
|
Readonly : सिर्फ़ गेटर एपीआई जनरेट करता है
Writeonce , ReadWrite : गेटर और सेटर एपीआई जनरेट करता है
ध्यान दें: हो सकता है कि ro. प्रीफ़िक्स वाली प्रॉपर्टी ReadWrite ऐक्सेस का इस्तेमाल न करें.
|
scope
|
Internal : सिर्फ़ मालिक ही ऐक्सेस कर सकता है.
Public : एनडीके (NDK) मॉड्यूल को छोड़कर, कोई भी व्यक्ति ऐक्सेस कर सकता है.
|
prop_name
|
दिए गए सिस्टम प्रॉपर्टी का नाम, उदाहरण के लिए
ro.build.date .
|
enum_values
|
(सिर्फ़ Enum , EnumList ) बार(|) से अलग की गई स्ट्रिंग
जिसमें संभावित ईनम वैल्यू मौजूद होती हैं. उदाहरण के लिए, value1|value2 .
|
integer_as_bool
|
(सिर्फ़ Boolean , BooleanList ) सेटर false और true के बजाय,
0 और 1 का इस्तेमाल करें.
|
legacy_prop_name
|
(ज़रूरी नहीं, सिर्फ़ Readonly प्रॉपर्टी) बुनियादी सिस्टम प्रॉपर्टी का लेगसी नाम. गैटर को कॉल करते समय, गैटर एपीआई prop_name को पढ़ने की कोशिश करता है. साथ ही, prop_name मौजूद न होने पर legacy_prop_name का इस्तेमाल करता है. किसी मौजूदा प्रॉपर्टी को बंद करने और नई प्रॉपर्टी पर ले जाने के लिए,
legacy_prop_name का इस्तेमाल करें.
|
C++, Java, और Rust में हर तरह की प्रॉपर्टी, नीचे बताए गए टाइप से मैप होगी.
टाइप | C++ | Java | Rust |
---|---|---|---|
बूलियन | std::optional<bool>
|
Optional<Boolean>
|
bool
|
पूर्णांक | std::optional<std::int32_t>
|
Optional<Integer>
|
i32
|
यूयूआईंट | std::optional<std::uint32_t>
|
Optional<Integer>
|
u32
|
ज़्यादा समय के लिए | std::optional<std::int64_t>
|
Optional<Long>
|
i64
|
यूलॉन्ग | std::optional<std::uint64_t>
|
Optional<Long>
|
u64
|
डबल | std::optional<double>
|
Optional<Double>
|
f64
|
स्ट्रिंग | std::optional<std::string>
|
Optional<String>
|
String
|
इनम | std::optional<{api_name}_values>
|
Optional<{api_name}_values>
|
{ApiName}Values
|
T सूची | std::vector<std::optional<T>>
|
List<T>
|
Vec<T>
|
यहां एक उदाहरण के तौर पर दिया गया है, जिसमें Sysprop के बारे में जानकारी देने वाली ऐसी फ़ाइल का इस्तेमाल किया गया है जिसमें तीन प्रॉपर्टी के बारे में बताया गया है:
# 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
}
सिस्टम की प्रॉपर्टी लाइब्रेरी के बारे में बताना
अब Sysprop की जानकारी वाली फ़ाइलों की मदद से, sysprop_library
मॉड्यूल तय किए जा सकते हैं.
sysprop_library
, C++, Java, और Rust के लिए एपीआई के तौर पर काम करता है. बिल्ड सिस्टम, sysprop_library
के हर इंस्टेंस के लिए अंदरूनी तौर पर एक rust_library
, एक java_library
, और एक cc_library
जनरेट करता है.
// File: Android.bp
sysprop_library {
name: "PlatformProperties",
srcs: ["android/sysprop/PlatformProperties.sysprop"],
property_owner: "Platform",
vendor_available: true,
}
एपीआई की जांच के लिए, आपको सोर्स में एपीआई लिस्ट वाली फ़ाइलें शामिल करनी होंगी. ऐसा करने के लिए,
एपीआई फ़ाइलें और api
डायरेक्ट्री बनाएं. api
डायरेक्ट्री को उसी डायरेक्ट्री में रखें जिसमें Android.bp
मौजूद है. एपीआई फ़ाइल के नाम <module_name>-current.txt
,
<module_name>-latest.txt
हैं. <module_name>-current.txt
में मौजूदा सोर्स कोड के एपीआई सिग्नेचर होते हैं और <module_name>-latest.txt
के पास सबसे नए फ़्रीज़ किए गए एपीआई सिग्नेचर होते हैं. बिल्ड सिस्टम यह जांच करता है कि इन एपीआई फ़ाइलों की तुलना, बिल्ड के समय जनरेट की गई एपीआई फ़ाइलों से करके की जाती है या नहीं. साथ ही, अगर current.txt
, सोर्स कोड से मेल नहीं खाता है, तो गड़बड़ी का मैसेज मिलता है और current.txt
फ़ाइल को अपडेट करने के निर्देश मिलते हैं. यहां डायरेक्ट्री और फ़ाइल
संगठन का एक उदाहरण दिया गया है:
├── api
│ ├── PlatformProperties-current.txt
│ └── PlatformProperties-latest.txt
└── Android.bp
जनरेट किए गए एपीआई का इस्तेमाल करने के लिए, Rust, Java, और C++ क्लाइंट मॉड्यूल को sysprop_library
से लिंक किया जा सकता है. बिल्ड सिस्टम, क्लाइंट से C++, Java, और Rust लाइब्रेरी जनरेट करने के लिए लिंक बनाता है. इससे क्लाइंट को जनरेट किए गए एपीआई का ऐक्सेस मिलता है.
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 लाइब्रेरी का नाम, sysprop_library
नाम को अंग्रेज़ी के छोटे अक्षरों में बदलने, .
और -
को _
से बदलने, और फिर lib
से पहले _rust
जोड़ने पर जनरेट होता है.
पिछले उदाहरण में, तय की गई प्रॉपर्टी को इस तरह ऐक्सेस किया जा सकता है.
रस्ट का उदाहरण:
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 का उदाहरण:
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++ का उदाहरण:
#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);
}
…
}
…