सिस्टम प्रॉपर्टी की मदद से, जानकारी आसानी से शेयर की जा सकती है. आम तौर पर,
कॉन्फ़िगरेशन, पूरे सिस्टम पर. हर पार्टीशन अपनी सिस्टम प्रॉपर्टी का इस्तेमाल कर सकता है
मिल सकता है. जब प्रॉपर्टी को सभी सेगमेंट में ऐक्सेस किया जाता है, तो समस्या हो सकती है. जैसे, /vendor
से तय की गई प्रॉपर्टी ऐक्सेस करना. Android 8.0 से,
कुछ पार्टिशन, जैसे कि /system
को अपग्रेड किया जा सकता है, जबकि /vendor
बाकी है
कोई बदलाव नहीं. क्योंकि सिस्टम प्रॉपर्टी, स्ट्रिंग की ग्लोबल डिक्शनरी
की-वैल्यू पेयर के बिना स्कीमा नहीं है, क्योंकि प्रॉपर्टी को स्थिर करना मुश्किल होता है. कॉन्टेंट बनाने
/system
पार्टीशन, उन प्रॉपर्टी को बदल या हटा सकता है जिन्हें /vendor
विभाजन बिना किसी सूचना के निर्भर करता है.
Android 10 रिलीज़ से, सभी पार्टीशन में ऐक्सेस की गई सिस्टम प्रॉपर्टी को Sysprop Description फ़ाइलों में स्कीमा के तौर पर सेव किया जाता है. साथ ही, प्रॉपर्टी को ऐक्सेस करने के लिए, C++ और Rust के लिए कंसक्रिट फ़ंक्शन और Java के लिए क्लास के तौर पर एपीआई जनरेट किए जाते हैं. इन एपीआई का इस्तेमाल करना ज़्यादा आसान होता है, क्योंकि इन्हें ऐक्सेस करने के लिए ro.build.date
जैसी कोई मैजिक स्ट्रिंग ज़रूरी नहीं होती. साथ ही, इन्हें स्टैटिक टाइप किया जा सकता है. बिल्ड के समय, एबीआई के स्थिर होने की जांच भी की जाती है. साथ ही, अगर कोई ऐसा बदलाव होता है जो काम नहीं करता है, तो बिल्ड रुक जाता है. यह जाँच, साफ़ तौर पर परिभाषित किए गए तरीके से काम करती है
विभाजनों के बीच इंटरफ़ेस दिखाई देता है. ये एपीआई भी एक जैसा अनुभव दे सकते हैं
Rust, Java और C++.
सिस्टम की प्रॉपर्टी को एपीआई के तौर पर परिभाषित करें
Sysprop Description फ़ाइलों (.sysprop
) की मदद से, सिस्टम प्रॉपर्टी को एपीआई के तौर पर तय करें. ये फ़ाइलें, protobuf के 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;
}
Sysprop की जानकारी वाली एक फ़ाइल में, प्रॉपर्टी का एक मैसेज होता है. इसमें प्रॉपर्टी के सेट के बारे में बताया जाता है. इसके फ़ील्ड के मतलब यहां दिए गए हैं.
फ़ील्ड | मतलब |
---|---|
owner
|
प्रॉपर्टी के मालिकाना हक वाले सेगमेंट पर सेट करें: Platform ,
Vendor या Odm .
|
module
|
इसका इस्तेमाल नेमस्पेस (C++) या स्टैटिक फ़ाइनल क्लास (Java) बनाने में किया जाता है, जिनमें
जनरेट किए गए एपीआई दिखाए जाते हैं. उदाहरण के लिए,
com.android.sysprop.BuildProperties
C++ में नेमस्पेस com::android::sysprop::BuildProperties होगा,
और Java में पैकेज में BuildProperties क्लास,
com.android.sysprop होगी.
|
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 के बजाय 0 और 1 और
true .
|
legacy_prop_name
|
(ज़रूरी नहीं, सिर्फ़ Readonly प्रॉपर्टी)
सिस्टम की प्रॉपर्टी. गैटर को कॉल करते समय, गैटर एपीआई पढ़ने की कोशिश करता है
prop_name और legacy_prop_name का इस्तेमाल करता है, अगर
prop_name मौजूद नहीं है. legacy_prop_name का इस्तेमाल तब करें, जब
किसी मौजूदा प्रॉपर्टी को रोकने और नई प्रॉपर्टी का इस्तेमाल करने के लिए.
|
C++, Java, और Rust में हर तरह की प्रॉपर्टी, नीचे बताए गए टाइप से मैप होगी.
टाइप | C++ | Java | रस्ट |
---|---|---|---|
बूलियन | 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
|
Enum | 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 के लिए एपीआई के तौर पर काम करता है. बिल्ड सिस्टम
आंतरिक तौर पर एक rust_library
, एक java_library
, और एक cc_library
जनरेट करता है
sysprop_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);
}
…
}
…