यह पृष्ठ एंड्रॉइड में सिस्टम गुणों को जोड़ने या परिभाषित करने के लिए एक विहित विधि प्रदान करता है, जिसमें मौजूदा सिस्टम गुणों को फिर से तैयार करने के लिए दिशानिर्देश शामिल हैं। सुनिश्चित करें कि आप रिफैक्टर करते समय दिशानिर्देशों का उपयोग करें, जब तक कि आपके पास एक मजबूत संगतता समस्या न हो जो अन्यथा निर्देशित करती हो।
चरण 1: सिस्टम प्रॉपर्टी को परिभाषित करना
जब आप कोई सिस्टम प्रॉपर्टी जोड़ते हैं, तो प्रॉपर्टी के लिए एक नाम तय करें और उसे SELinux प्रॉपर्टी संदर्भ के साथ संबद्ध करें। यदि कोई उपयुक्त मौजूदा संदर्भ नहीं है, तो एक नया संदर्भ बनाएं। संपत्ति तक पहुँचते समय नाम का उपयोग किया जाता है; संपत्ति संदर्भ का उपयोग SELinux के संदर्भ में पहुंच को नियंत्रित करने के लिए किया जाता है। नाम कोई भी स्ट्रिंग हो सकते हैं, लेकिन AOSP अनुशंसा करता है कि आप उन्हें स्पष्ट करने के लिए एक संरचित प्रारूप का पालन करें।
संपत्ति का नाम
स्नेक_केस केसिंग के साथ इस प्रारूप का उपयोग करें:
[{prefix}.]{group}[.{subgroup}]*.{name}[.{type}]
तत्व prefix
के लिए या तो "" (छोड़ा गया), ro
(केवल एक बार सेट की गई संपत्तियों के लिए), या persist
(रीबूट के दौरान बनी रहने वाली संपत्तियों के लिए) का उपयोग करें।
चेतावनियां
ro
उपयोग केवल तभी करें जब आप आश्वस्त हों कि आपको भविष्य में लिखने योग्य prefix
की आवश्यकता नहीं है। ** ro
उपसर्ग निर्दिष्ट न करें। ** इसके बजाय, prefix
केवल पढ़ने योग्य (दूसरे शब्दों में, केवल init
द्वारा लिखने योग्य) बनाने के लिए सेपॉलिसी पर भरोसा करें।
केवल persist
उपयोग करें जब आप आश्वस्त हों कि मान रिबूट के दौरान कायम रहना चाहिए, और सिस्टम गुणों का उपयोग करना आपके लिए एकमात्र विकल्प है। (विवरण के लिए तैयारी अनुभाग देखें।)
Google उन सिस्टम गुणों की सख्ती से समीक्षा करता है जिनमें ro
या persist
गुण होते हैं।
group
शब्द का प्रयोग संबंधित गुणों को एकत्रित करने के लिए किया जाता है। इसका उद्देश्य audio
या telephony
के उपयोग के समान एक सबसिस्टम नाम होना है। sys
, system
, dev
, default
, या config
जैसे अस्पष्ट या अतिभारित शब्दों का उपयोग न करें ।
किसी प्रक्रिया के डोमेन प्रकार के नाम का उपयोग करना आम बात है जिसमें सिस्टम गुणों तक विशेष पढ़ने या लिखने की पहुंच होती है। उदाहरण के लिए, उन सिस्टम गुणों के लिए जिनमें vold
प्रक्रिया के पास लिखने की पहुंच है, समूह नाम के रूप में vold
(प्रक्रिया के लिए डोमेन प्रकार का नाम) का उपयोग करना आम बात है।
यदि आवश्यक हो, तो गुणों को और अधिक वर्गीकृत करने के लिए subgroup
जोड़ें, लेकिन इस तत्व का वर्णन करने के लिए अस्पष्ट या अतिभारित शब्दों से बचें। (आपके पास एक से अधिक subgroup
भी हो सकते हैं।)
कई समूह नाम पहले ही परिभाषित किए जा चुके हैं. system/sepolicy/private/property_contexts
फ़ाइल की जांच करें और जहां संभव हो नए समूह नाम बनाने के बजाय मौजूदा समूह नामों का उपयोग करें। निम्न तालिका अक्सर उपयोग किए जाने वाले समूह नामों के उदाहरण प्रदान करती है।
कार्यक्षेत्र | समूह (और उपसमूह) |
---|---|
ब्लूटूथ संबंधी | bluetooth |
कर्नेल cmdline से sysprops | boot |
sysprops जो किसी निर्माण की पहचान करते हैं | build |
टेलीफोनी संबंधी | telephony |
ऑडियो संबंधी | audio |
ग्राफ़िक्स संबंधी | graphics |
वोल्ड संबंधित | vold |
निम्नलिखित पिछले रेगेक्स उदाहरण में name
और type
के उपयोग को परिभाषित करता है।
[{prefix}.]{group}[.{subgroup}]*.{name}[.{type}]
name
एक समूह के भीतर एक सिस्टम प्रॉपर्टी की पहचान करता है।type
एक वैकल्पिक तत्व है जो सिस्टम प्रॉपर्टी के प्रकार या इरादे को स्पष्ट करता है। उदाहरण के लिए, किसी sysprop कोaudio.awesome_feature_enabled
या केवलaudio.awesome_feature
नाम देने के बजाय, सिस्टम प्रॉपर्टी प्रकार और इरादे को प्रतिबिंबित करने के लिए इसका नाम बदलकरaudio.awesome_feature.enabled
रखें।
इसका प्रकार क्या होना चाहिए इसके बारे में कोई विशिष्ट नियम नहीं है; ये उपयोग अनुशंसाएँ हैं:
-
enabled
: यदि प्रकार एक बूलियन सिस्टम प्रॉपर्टी है जिसका उपयोग किसी सुविधा को चालू या बंद करने के लिए किया जाता है तो इसका उपयोग करें। -
config
: यदि इरादा यह स्पष्ट करना है कि सिस्टम प्रॉपर्टी सिस्टम की गतिशील स्थिति का प्रतिनिधित्व नहीं करती है तो इसका उपयोग करें; यह एक पूर्व-कॉन्फ़िगर मान का प्रतिनिधित्व करता है (उदाहरण के लिए, केवल पढ़ने योग्य चीज़)। -
List
: यदि यह एक सिस्टम प्रॉपर्टी है जिसका मूल्य एक सूची है तो इसका उपयोग करें। -
Timeoutmillis
: यदि यह एमएस की इकाइयों में टाइमआउट मान के लिए एक सिस्टम प्रॉपर्टी है तो इसका उपयोग करें।
उदाहरण:
-
persist.radio.multisim.config
-
drm.service.enabled
संपत्ति प्रसंग
नई SELinux संपत्ति संदर्भ योजना बेहतर विवरणात्मकता और अधिक वर्णनात्मक नामों की अनुमति देती है। संपत्ति के नामों के लिए उपयोग किए जाने वाले प्रारूप के समान, AOSP निम्नलिखित प्रारूप की अनुशंसा करता है:
{group}[_{subgroup}]*_prop
शर्तों को इस प्रकार परिभाषित किया गया है:
group
और subgroup
का वही अर्थ है जो पिछले नमूना रेगेक्स के लिए परिभाषित किया गया है। उदाहरण के लिए, vold_config_prop
उन गुणों को दर्शाता है जो एक विक्रेता से कॉन्फ़िगरेशन हैं और vendor_init
द्वारा सेट किए जाने हैं, जबकि vold_status_prop
या सिर्फ vold_prop
उन गुणों को दर्शाता है जो vold
की वर्तमान स्थिति को उजागर करते हैं।
किसी संपत्ति संदर्भ का नामकरण करते समय, ऐसे नाम चुनें जो गुणों के सामान्य उपयोग को दर्शाते हों। विशेष रूप से, निम्नलिखित प्रकार के शब्दों से बचें:
- ऐसे शब्द जो बहुत सामान्य और अस्पष्ट लगते हैं, जैसे
sys
,system
,default
। - वे शब्द जो सीधे पहुंच को एन्कोड करते हैं: जैसे कि
exported
,apponly
,ro
,public
,private
।
नाम के उपयोग को प्राथमिकता दें, जैसे कि vold_config_prop
से लेकर exported_vold_prop
, या vold_vendor_writable_prop
, इत्यादि।
प्रकार
संपत्ति का प्रकार तालिका में सूचीबद्ध निम्नलिखित में से एक हो सकता है।
प्रकार | परिभाषा |
---|---|
बूलियन | true या सत्य के लिए 1 , false या असत्य के लिए 0 |
पूर्णांक | 64-बिट पूर्णांक पर हस्ताक्षर किए |
अहस्ताक्षरित पूर्णांक | अहस्ताक्षरित 64-बिट पूर्णांक |
दोहरा | डबल-परिशुद्धता फ़्लोटिंग पॉइंट |
डोरी | कोई भी वैध UTF-8 स्ट्रिंग |
enum | मान रिक्त स्थान के बिना कोई भी वैध UTF-8 स्ट्रिंग हो सकते हैं |
उपरोक्त की सूची | अल्पविराम ( , ) का प्रयोग सीमांकक के रूप में किया जाता हैपूर्णांक सूची [1, 2, 3] 1,2,3 के रूप में संग्रहीत किया जाता है |
आंतरिक रूप से, सभी गुण स्ट्रिंग के रूप में संग्रहीत होते हैं। आप प्रकार को property_contexts
फ़ाइल के रूप में निर्दिष्ट करके लागू कर सकते हैं। अधिक जानकारी के लिए, चरण 3 में property_contexts
देखें।
चरण 2: आवश्यक पहुंच स्तर निर्धारित करना
चार सहायक मैक्रोज़ हैं जो एक संपत्ति को परिभाषित करते हैं।
अभिगम्यता प्रकार | अर्थ |
---|---|
system_internal_prop | वे गुण जिनका उपयोग केवल /system में किया जाता है |
system_restricted_prop | गुण जो /system के बाहर पढ़े जाते हैं, लेकिन लिखे नहीं जाते |
system_vendor_config_prop | गुण जो /system बाहर पढ़े जाते हैं, और केवल vendor_init द्वारा लिखे जाते हैं |
system_public_prop | वे गुण जो /system बाहर पढ़े और लिखे जाते हैं |
सिस्टम गुणों तक पहुंच का दायरा यथासंभव सीमित रखें। अतीत में, व्यापक पहुंच के कारण ऐप टूट-फूट और सुरक्षा कमजोरियां हुई हैं। स्कोपिंग करते समय निम्नलिखित प्रश्नों पर विचार करें:
- क्या इस सिस्टम प्रॉपर्टी को जारी रखने की आवश्यकता है? (यदि हां, तो क्यों?)
- किस प्रक्रिया को इस संपत्ति तक पढ़ने की पहुंच होनी चाहिए?
- किस प्रक्रिया को इस संपत्ति तक लिखने की पहुंच होनी चाहिए?
पहुंच के लिए उचित दायरा निर्धारित करने के लिए पिछले प्रश्नों और निम्नलिखित निर्णय वृक्ष का उपयोग उपकरण के रूप में करें।
चित्र 1. सिस्टम गुणों तक पहुंच का दायरा निर्धारित करने के लिए निर्णय वृक्ष
चरण 3: इसे सिस्टम/सेपॉलिसी में जोड़ना
sysprop तक पहुँचते समय, SELinux प्रक्रियाओं की पहुँच को नियंत्रित करता है। आपके द्वारा यह निर्धारित करने के बाद कि किस स्तर की पहुंच की आवश्यकता है, system/sepolicy
के तहत संपत्ति संदर्भों को परिभाषित करें, साथ ही अतिरिक्त अनुमति और नेवरअल्लो नियमों के साथ कि किन प्रक्रियाओं को पढ़ने या लिखने की अनुमति है (और क्या नहीं)।
सबसे पहले, system/sepolicy/public/property.te
फ़ाइल में संपत्ति संदर्भ को परिभाषित करें। यदि संपत्ति सिस्टम-आंतरिक है, तो इसे system/sepolicy/private/property.te
फ़ाइल में परिभाषित करें। system_[accessibility]_prop([context])
मैक्रोज़ में से एक का उपयोग करें जो आपके सिस्टम प्रॉपर्टी के लिए आवश्यक पहुंच प्रदान करता है। यह system/sepolicy/public/property.te
फ़ाइल के लिए एक उदाहरण है:
system_public_prop(audio_foo_prop)
system_vendor_config_prop(audio_bar_prop)
system/sepolicy/private/property.te
फ़ाइल में जोड़ने का उदाहरण:
system_internal_prop(audio_baz_prop)
दूसरा, संपत्ति के संदर्भ में पढ़ने और (या) लिखने की पहुंच प्रदान करें। system/sepolicy/public/{domain}.te
या system/sepolicy/private/{domain}.te
फ़ाइल में पहुंच प्रदान करने के लिए set_prop
और get_prop
मैक्रोज़ का उपयोग करें। जब भी संभव हो private
प्रयोग करें; public
केवल तभी उपयुक्त है जब set_prop
या get_prop
मैक्रो कोर डोमेन के बाहर किसी भी डोमेन को प्रभावित करता है।
उदाहरण, system/sepolicy/private/audio.te
फ़ाइल में:
set_prop(audio, audio_foo_prop)
set_prop(audio, audio_bar_prop)
उदाहरण, system/sepolicy/public/domain.te
फ़ाइल में:
get_prop(domain, audio_bar_prop)
तीसरा, मैक्रो द्वारा दायरे में आने वाली पहुंच को और कम करने के लिए कुछ नेवरअलाउ नियम जोड़ें। उदाहरण के लिए, मान लें कि आपने system_restricted_prop
का उपयोग किया है क्योंकि आपके सिस्टम गुणों को विक्रेता प्रक्रियाओं द्वारा पढ़ा जाना चाहिए। यदि सभी विक्रेता प्रक्रियाओं के लिए रीड एक्सेस की आवश्यकता नहीं है, और यह केवल प्रक्रियाओं के एक निश्चित सेट (जैसे कि vendor_init
) के लिए आवश्यक है, तो उन विक्रेता प्रक्रियाओं को प्रतिबंधित करें जिन्हें रीड एक्सेस की आवश्यकता नहीं है।
लिखने और पढ़ने की पहुंच को प्रतिबंधित करने के लिए निम्नलिखित सिंटैक्स का उपयोग करें:
लिखने की पहुंच प्रतिबंधित करने के लिए:
neverallow [domain] [context]:property_service set;
पढ़ने की पहुंच प्रतिबंधित करने के लिए:
neverallow [domain] [context]:file no_rw_file_perms;
यदि नेवरअलाउ नियम किसी विशिष्ट डोमेन से जुड़ा हुआ है system/sepolicy/private/{domain}.te
फ़ाइल में नेवरअलाउ नियम रखें। व्यापक नेवरअलाउ नियमों के लिए, जहां भी उचित हो, सामान्य डोमेन का उपयोग करें:
-
system/sepolicy/private/property.te
-
system/sepolicy/private/coredomain.te
-
system/sepolicy/private/domain.te
system/sepolicy/private/audio.te
फ़ाइल में, निम्नलिखित रखें:
neverallow {
domain -init -audio
} {audio_foo_prop audio_bar_prop}:property_service set;
system/sepolicy/private/property.te
फ़ाइल में, निम्नलिखित रखें:
neverallow {
domain -coredomain -vendor_init
} audio_prop:file no_rw_file_perms;
ध्यान दें कि {domain -coredomain}
सभी विक्रेता प्रक्रियाओं को कैप्चर करता है। तो {domain -coredomain -vendor_init}
अर्थ है " vendor_init
को छोड़कर सभी विक्रेता प्रक्रियाएँ।"
अंत में, सिस्टम प्रॉपर्टी को प्रॉपर्टी संदर्भ के साथ संबद्ध करें। यह सुनिश्चित करता है कि जो पहुंच प्रदान की गई है और संपत्ति संदर्भों पर लागू होने वाले कभी भी अनुमति न दें नियम वास्तविक संपत्तियों पर लागू होते हैं। ऐसा करने के लिए, property_contexts
फ़ाइल में एक प्रविष्टि जोड़ें, एक फ़ाइल जो सिस्टम गुणों और संपत्ति संदर्भों के बीच मैपिंग का वर्णन करती है। इस फ़ाइल में, आप या तो एक एकल संपत्ति निर्दिष्ट कर सकते हैं, या किसी संदर्भ में मैप की जाने वाली संपत्तियों के लिए एक उपसर्ग निर्दिष्ट कर सकते हैं।
यह एकल संपत्ति को मैप करने का सिंटैक्स है:
[property_name] u:object_r:[context_name]:s0 exact [type]
यह उपसर्ग को मैप करने का सिंटैक्स है:
[property_name_prefix] u:object_r:[context_name]:s0 prefix [type]
आप वैकल्पिक रूप से संपत्ति का प्रकार निर्दिष्ट कर सकते हैं, जो निम्नलिखित में से एक हो सकता है:
-
bool
-
int
-
uint
-
double
-
enum [list of possible values...]
-
string
(सूची गुणों के लिएstring
उपयोग करें।)
सुनिश्चित करें कि जब भी संभव हो प्रत्येक प्रविष्टि का अपना निर्दिष्ट प्रकार हो, क्योंकि property
सेट करते समय type
लागू किया जाता है। निम्नलिखित उदाहरण दिखाता है कि मैपिंग कैसे लिखें:
# binds a boolean property "ro.audio.status.enabled"
# to the context "audio_foo_prop"
ro.audio.status.enabled u:object_r:audio_foo_prop:s0 exact bool
# binds a boolean property "vold.decrypt.status"
# to the context "vold_foo_prop"
# The property can only be set to one of these: on, off, unknown
vold.decrypt.status u:object_r:vold_foo_prop:s0 exact enum on off unknown
# binds any properties starting with "ro.audio.status."
# to the context "audio_bar_prop", such as
# "ro.audio.status.foo", or "ro.audio.status.bar.baz", and so on.
ro.audio.status. u:object_r:audio_bar_prop:s0 prefix
जब एक सटीक प्रविष्टि और एक उपसर्ग प्रविष्टि में टकराव होता है, तो सटीक प्रविष्टि को प्राथमिकता दी जाती है। अधिक उदाहरणों के लिए, system/sepolicy/private/property_contexts
देखें।
चरण 4: स्थिरता आवश्यकताओं का निर्धारण
स्थिरता सिस्टम गुणों का एक और पहलू है, और यह पहुंच से भिन्न है। स्थिरता इस बारे में है कि भविष्य में सिस्टम प्रॉपर्टी को बदला जा सकता है या नहीं (उदाहरण के लिए नाम बदला जा सकता है, या हटाया भी जा सकता है)। यह विशेष रूप से महत्वपूर्ण है क्योंकि एंड्रॉइड ओएस मॉड्यूलर बन गया है। ट्रेबल के साथ, सिस्टम, विक्रेता और उत्पाद विभाजन को एक दूसरे से स्वतंत्र रूप से अपडेट किया जा सकता है। मेनलाइन के साथ, ओएस के कुछ हिस्सों को अद्यतन करने योग्य मॉड्यूल (एपेक्स या एपीके में) के रूप में मॉड्यूलर किया जाता है।
यदि कोई सिस्टम प्रॉपर्टी सॉफ़्टवेयर के अद्यतन करने योग्य टुकड़ों में उपयोग के लिए है, उदाहरण के लिए सिस्टम और विक्रेता विभाजन में, तो यह स्थिर होना चाहिए। हालाँकि, यदि इसका उपयोग केवल, उदाहरण के लिए, एक विशिष्ट मेनलाइन मॉड्यूल के भीतर किया जाता है, तो आप इसका नाम, प्रकार, या संपत्ति संदर्भ बदल सकते हैं, और यहां तक कि इसे हटा भी सकते हैं।
सिस्टम प्रॉपर्टी की स्थिरता निर्धारित करने के लिए निम्नलिखित प्रश्न पूछें:
- क्या यह सिस्टम प्रॉपर्टी साझेदारों द्वारा कॉन्फ़िगर करने के लिए है (या प्रति डिवाइस अलग-अलग कॉन्फ़िगर की गई है)? यदि हां, तो यह स्थिर होना चाहिए.
- क्या यह एओएसपी-परिभाषित सिस्टम प्रॉपर्टी उस कोड (प्रक्रिया नहीं) से लिखने या पढ़ने के लिए है जो
vendor.img
याproduct.img
जैसे गैर-सिस्टम विभाजन में मौजूद है? यदि हां, तो यह स्थिर होना चाहिए. - क्या इस सिस्टम प्रॉपर्टी को मेनलाइन मॉड्यूल या मेनलाइन मॉड्यूल और प्लेटफ़ॉर्म के गैर-अद्यतन योग्य भाग तक एक्सेस किया जा सकता है? यदि हां, तो यह स्थिर होना चाहिए.
स्थिर सिस्टम गुणों के लिए, प्रत्येक को औपचारिक रूप से एक एपीआई के रूप में परिभाषित करें और सिस्टम संपत्ति तक पहुंचने के लिए एपीआई का उपयोग करें, जैसा कि चरण 6 में बताया गया है।
चरण 5: निर्माण समय पर गुण सेट करना
मेकफ़ाइल वेरिएबल्स के साथ बिल्ड समय पर गुण सेट करें। तकनीकी रूप से, मानों को {partition}/build.prop
पर बेक किया जाता है। फिर init
गुण सेट करने के लिए {partition}/build.prop
पढ़ता है। ऐसे चर के दो सेट हैं: PRODUCT_{PARTITION}_PROPERTIES
और TARGET_{PARTITION}_PROP
।
PRODUCT_{PARTITION}_PROPERTIES
में संपत्ति मूल्यों की एक सूची शामिल है। सिंटैक्स है {prop}={value}
या {prop}?={value}
.
{prop}={value}
एक सामान्य असाइनमेंट है जो यह सुनिश्चित करता है कि {prop}
को {value}
पर सेट किया गया है; एक संपत्ति के लिए केवल एक ही ऐसा असाइनमेंट संभव है।
{prop}?={value}
एक वैकल्पिक असाइनमेंट है; {prop}
केवल तभी {value}
पर सेट होता है जब कोई {prop}={value}
असाइनमेंट न हो। यदि एकाधिक वैकल्पिक असाइनमेंट मौजूद हैं, तो पहला जीतता है।
# sets persist.traced.enable to 1 with system/build.prop
PRODUCT_SYSTEM_PROPERTIES += persist.traced.enable=1
# sets ro.zygote to zygote32 with system/build.prop
# but only when there are no other assignments to ro.zygote
# optional are useful when giving a default value to a property
PRODUCT_SYSTEM_PROPERTIES += ro.zygote?=zygote32
# sets ro.config.low_ram to true with vendor/build.prop
PRODUCT_VENDOR_PROPERTIES += ro.config.low_ram=true
TARGET_{PARTITION}_PROP
में फ़ाइलों की एक सूची होती है, जो सीधे {partition}/build.prop
पर उत्सर्जित होती है। प्रत्येक फ़ाइल में {prop}={value}
जोड़ियों की एक सूची होती है।
# example.prop
ro.cp_system_other_odex=0
ro.adb.secure=0
ro.control_privapp_permissions=disable
# emits example.prop to system/build.prop
TARGET_SYSTEM_PROP += example.prop
अधिक विवरण के लिए, build/make/core/sysprop.mk
देखें।
चरण 6: रनटाइम पर संपत्तियों तक पहुंचें
बेशक, गुणों को रनटाइम पर पढ़ा और लिखा जा सकता है।
इनिट स्क्रिप्ट
Init स्क्रिप्ट फ़ाइलें (आमतौर पर *.rc फ़ाइलें) किसी प्रॉपर्टी को ${prop}
या ${prop:-default}
द्वारा पढ़ सकती हैं, एक क्रिया सेट कर सकती हैं जो तब चलती है जब कोई प्रॉपर्टी एक विशिष्ट मान बन जाती है, और setprop
उपयोग करके गुण लिख सकती हैं आज्ञा।
# when persist.device_config.global_settings.sys_traced becomes 1,
# set persist.traced.enable to 1
on property:persist.device_config.global_settings.sys_traced=1
setprop persist.traced.enable 1
# when security.perf_harden becomes 0,
# write /proc/sys/kernel/sample_rate to the value of
# debug.sample_rate. If it's empty, write -100000 instead
on property:security.perf_harden=0
write /proc/sys/kernel/sample_rate ${debug.sample_rate:-100000}
गेटप्रॉप और सेटप्रॉप शेल कमांड
आप गुणों को पढ़ने या लिखने के लिए क्रमशः getprop
या setprop
शेल कमांड का उपयोग कर सकते हैं। अधिक जानकारी के लिए, getprop --help
या setprop --help
आह्वान करें।
$ adb shell getprop ro.vndk.version
$
$ adb shell setprop security.perf_harden 0
सी++/जावा/रस्ट के लिए एपीआई के रूप में सिसप्रॉप
एपीआई के रूप में sysprop के साथ, आप सिस्टम गुणों को परिभाषित कर सकते हैं और ऑटो-जेनरेटेड एपीआई का उपयोग कर सकते हैं जो ठोस और टाइप किए गए हैं। Public
के साथ scope
निर्धारित करने से उत्पन्न एपीआई सीमाओं के पार मॉड्यूल के लिए उपलब्ध हो जाती है, और एपीआई स्थिरता सुनिश्चित होती है। यहां एक .sysprop
फ़ाइल, एक Android.bp
मॉड्यूल और उनका उपयोग करने वाले C++, Java और रस्ट कोड का एक नमूना दिया गया है।
# AudioProps.sysprop
# module becomes static class (Java) / namespace (C++) for serving API
module: "android.sysprop.AudioProps"
# owner can be Platform or Vendor or Odm
owner: Platform
# one prop defines one property
prop {
prop_name: "ro.audio.volume.level"
type: Integer
scope: Public
access: ReadWrite
api_name: "volume_level"
}
…
// Android.bp
sysprop_library {
name: "AudioProps",
srcs: ["android/sysprop/AudioProps.sysprop"],
property_owner: "Platform",
}
// Rust, Java and C++ modules can link against the sysprop_library
rust_binary {
rustlibs: ["libaudioprops_rust"],
…
}
java_library {
static_libs: ["AudioProps"],
…
}
cc_binary {
static_libs: ["libAudioProps"],
…
}
// Rust code accessing generated API.
// Get volume. Use 50 as the default value.
let vol = audioprops::volume_level()?.unwrap_or_else(50);
// Java codes accessing generated API
// get volume. use 50 as the default value.
int vol = android.sysprop.AudioProps.volume_level().orElse(50);
// add 10 to the volume level.
android.sysprop.AudioProps.volume_level(vol + 10);
// C++ codes accessing generated API
// get volume. use 50 as the default value.
int vol = android::sysprop::AudioProps::volume_level().value_or(50);
// add 10 to the volume level.
android::sysprop::AudioProps::volume_level(vol + 10);
अधिक जानकारी के लिए, सिस्टम गुणों को एपीआई के रूप में कार्यान्वित करना देखें।
सी/सी++, जावा और रस्ट निम्न-स्तरीय संपत्ति फ़ंक्शन और विधियां
जब संभव हो, तो Sysprop को API के रूप में उपयोग करें, भले ही निम्न-स्तरीय C/C++ या रस्ट फ़ंक्शंस या निम्न-स्तरीय जावा विधियाँ आपके लिए उपलब्ध हों।
libc
, libbase
, और libcutils
C++ सिस्टम प्रॉपर्टी फ़ंक्शंस प्रदान करते हैं। libc
में अंतर्निहित API है, जबकि libbase
और libcutils
फ़ंक्शन रैपर हैं। यदि यह संभव है, तो libbase
sysprop फ़ंक्शंस का उपयोग करें; वे सबसे सुविधाजनक हैं, और होस्ट बायनेरिज़ libbase
फ़ंक्शंस का उपयोग कर सकते हैं। अधिक विवरण के लिए, sys/system_properties.h
( libc
), android-base/properties.h
( libbase
), और cutils/properties.h
( libcutils
) देखें।
android.os.SystemProperties
वर्ग जावा सिस्टम प्रॉपर्टी विधियाँ प्रदान करता है।
rustutils::system_properties
मॉड्यूल रस्ट सिस्टम प्रॉपर्टी फ़ंक्शंस और प्रकार प्रदान करता है।
परिशिष्ट: विक्रेता-विशिष्ट गुण जोड़ना
भागीदार (पिक्सेल विकास के संदर्भ में काम करने वाले Googlers सहित) हार्डवेयर-विशिष्ट (या डिवाइस-विशिष्ट) सिस्टम गुणों को परिभाषित करना चाहते हैं। विक्रेता-विशिष्ट संपत्तियाँ भागीदार-स्वामित्व वाली संपत्तियाँ हैं जो उनके स्वयं के हार्डवेयर या डिवाइस के लिए अद्वितीय हैं, न कि प्लेटफ़ॉर्म के लिए। चूँकि ये हार्डवेयर या डिवाइस पर निर्भर हैं, इनका उपयोग /vendor
या /odm
विभाजन के भीतर किया जाना है।
प्रोजेक्ट ट्रेबल के बाद से, प्लेटफ़ॉर्म संपत्तियों और विक्रेता संपत्तियों को परस्पर विरोधी होने से बचाने के लिए पूरी तरह से विभाजित कर दिया गया है। निम्नलिखित वर्णन करता है कि विक्रेता गुणों को कैसे परिभाषित किया जाए, और बताया गया है कि कौन से विक्रेता गुणों का हमेशा उपयोग किया जाना चाहिए।
संपत्ति और संदर्भ नामों पर नामस्थान
सभी विक्रेता संपत्तियों को उनके और अन्य विभाजनों के गुणों के बीच टकराव को रोकने के लिए निम्नलिखित उपसर्गों में से एक के साथ शुरू करना होगा।
-
ctl.odm.
-
ctl.vendor.
-
ctl.start$odm.
-
ctl.start$vendor.
-
ctl.stop$odm.
-
ctl.stop$vendor.
-
init.svc.odm.
-
init.svc.vendor.
-
ro.odm.
-
ro.vendor.
-
odm.
-
persist.odm.
-
persist.vendor.
-
vendor.
ध्यान दें कि ro.hardware.
उपसर्ग के रूप में अनुमति है, लेकिन केवल अनुकूलता के लिए। सामान्य संपत्तियों के लिए इसका उपयोग न करें.
निम्नलिखित सभी उदाहरण पूर्ववर्ती सूचीबद्ध उपसर्गों में से एक का उपयोग करते हैं:
-
vendor.display.primary_red
-
persist.vendor.faceauth.use_disk_cache
-
ro.odm.hardware.platform
सभी विक्रेता संपत्ति संदर्भ vendor_
से शुरू होने चाहिए। यह अनुकूलता के लिए भी है. निम्नलिखित उदाहरण हैं:
-
vendor_radio_prop
। -
vendor_faceauth_prop
। -
vendor_usb_prop
।
संपत्तियों को नाम देना और उनका रखरखाव करना विक्रेता की जिम्मेदारी है, इसलिए विक्रेता के नामस्थान आवश्यकताओं के अलावा, चरण 2 में सुझाए गए प्रारूप का पालन करें।
विक्रेता-विशिष्ट SEPolicy नियम और संपत्ति_संदर्भ
विक्रेता संपत्तियों को vendor_internal_prop
मैक्रो द्वारा परिभाषित किया जा सकता है। आपके द्वारा परिभाषित विक्रेता-विशिष्ट नियमों को BOARD_VENDOR_SEPOLICY_DIRS
निर्देशिका में रखें। उदाहरण के लिए, मान लीजिए कि आप कोरल में एक विक्रेता फेसऑथ प्रॉपर्टी को परिभाषित कर रहे हैं।
BoardConfig.mk
फ़ाइल में (या किसी भी BoardConfig.mk
में शामिल है), निम्नलिखित डालें:
BOARD_VENDOR_SEPOLICY_DIRS := device/google/coral-sepolicy
device/google/coral-sepolicy/private/property.te
फ़ाइल में, निम्नलिखित डालें:
vendor_internal_prop(vendor_faceauth_prop)
device/google/coral-sepolicy/private/property_contexts
फ़ाइल में, निम्नलिखित डालें:
vendor.faceauth.trace u:object_r:vendor_faceauth_prop:s0 exact bool
विक्रेता संपत्तियों की सीमाएँ
चूँकि सिस्टम और उत्पाद विभाजन विक्रेता पर निर्भर नहीं हो सकते, इसलिए कभी भी विक्रेता गुणों को system
, system-ext
, या product
विभाजन से एक्सेस करने की अनुमति न दें।
परिशिष्ट: मौजूदा संपत्तियों का नाम बदलना
जब आपको किसी संपत्ति को हटा कर नई संपत्ति में ले जाना हो, तो अपनी मौजूदा संपत्तियों का नाम बदलने के लिए एपीआई के रूप में Sysprop का उपयोग करें। यह विरासत नाम और नई संपत्ति नाम दोनों को निर्दिष्ट करके पश्चगामी संगतता बनाए रखता है। विशेष रूप से, आप .sysprop
फ़ाइल में legacy_prop_name
फ़ील्ड द्वारा लिगेसी नाम सेट कर सकते हैं। जेनरेट किया गया एपीआई prop_name
पढ़ने का प्रयास करता है, और यदि prop_name
मौजूद नहीं है तो legacy_prop_name
उपयोग करता है।
उदाहरण के लिए, निम्न चरणों का नाम बदलकर awesome_feature_foo_enabled
से foo.awesome_feature.enabled
।
foo.sysprop
फ़ाइल में
module: "android.sysprop.foo"
owner: Platform
prop {
api_name: "is_awesome_feature_enabled"
type: Boolean
scope: Public
access: Readonly
prop_name: "foo.awesome_feature.enabled"
legacy_prop_name: "awesome_feature_foo_enabled"
}
C++ कोड में
// is_awesome_feature_enabled() reads "foo.awesome_feature.enabled".
// If it doesn't exist, reads "awesome_feature_foo_enabled" instead
using android::sysprop::foo;
bool enabled = foo::is_awesome_feature_enabled().value_or(false);
निम्नलिखित चेतावनियों पर ध्यान दें:
सबसे पहले, आप sysprop का प्रकार नहीं बदल सकते। उदाहरण के लिए, आप एक
int
प्रोप को एकstring
प्रोप में नहीं बना सकते। आप केवल नाम बदल सकते हैं.दूसरा, केवल पढ़ी गई एपीआई ही लीगेसी नाम पर वापस आती है। राइट एपीआई वापस नहीं आती है। यदि सिसप्रॉप लिखने योग्य है, तो आप उसका नाम नहीं बदल सकते।