সিস্টেম বৈশিষ্ট্য তথ্য শেয়ার করার একটি সুবিধাজনক উপায় প্রদান করে, সাধারণত কনফিগারেশন, সিস্টেম-ব্যাপী। প্রতিটি পার্টিশন অভ্যন্তরীণভাবে নিজস্ব সিস্টেম বৈশিষ্ট্য ব্যবহার করতে পারে। পার্টিশন জুড়ে বৈশিষ্ট্যগুলি অ্যাক্সেস করা হলে একটি সমস্যা ঘটতে পারে, যেমন /vendor
অ্যাক্সেসিং /system
-সংজ্ঞায়িত বৈশিষ্ট্য। Android 8.0 থেকে, কিছু পার্টিশন, যেমন /system
, আপগ্রেড করা যেতে পারে, যখন /vendor
অপরিবর্তিত থাকে। যেহেতু সিস্টেমের বৈশিষ্ট্যগুলি স্কিমা ছাড়াই স্ট্রিং কী-মানের জোড়াগুলির একটি বিশ্বব্যাপী অভিধান, তাই বৈশিষ্ট্যগুলিকে স্থিতিশীল করা কঠিন৷ /system
পার্টিশন কোন নোটিশ ছাড়াই /vendor
পার্টিশন নির্ভর করে এমন বৈশিষ্ট্যগুলি পরিবর্তন বা অপসারণ করতে পারে।
অ্যান্ড্রয়েড 10 রিলিজ দিয়ে শুরু করে, পার্টিশন জুড়ে অ্যাক্সেস করা সিস্টেমের বৈশিষ্ট্যগুলিকে সিসপ্রপ বর্ণনা ফাইলগুলিতে পরিকল্পিত করা হয়, এবং বৈশিষ্ট্যগুলি অ্যাক্সেস করার জন্য APIগুলি C++ এবং মরিচা এবং জাভার ক্লাসের জন্য কংক্রিট ফাংশন হিসাবে তৈরি করা হয়। এই APIগুলি ব্যবহার করা আরও সুবিধাজনক কারণ অ্যাক্সেসের জন্য কোনও ম্যাজিক স্ট্রিং (যেমন ro.build.date
) এর প্রয়োজন নেই এবং কারণ সেগুলি স্ট্যাটিকভাবে টাইপ করা যেতে পারে। বিল্ড টাইমে ABI স্থায়িত্বও পরীক্ষা করা হয় এবং বেমানান পরিবর্তন ঘটলে বিল্ড ব্রেক হয়ে যায়। এই চেকটি পার্টিশনের মধ্যে স্পষ্টভাবে সংজ্ঞায়িত ইন্টারফেস হিসাবে কাজ করে। এই APIগুলি মরিচা, জাভা এবং C++ এর মধ্যে সামঞ্জস্য প্রদান করতে পারে।
API হিসাবে সিস্টেম বৈশিষ্ট্য সংজ্ঞায়িত করুন
Sysprop বর্ণনা ফাইল ( .sysprop
) সহ এপিআই হিসাবে সিস্টেম বৈশিষ্ট্যগুলিকে সংজ্ঞায়িত করুন, যা নিম্নলিখিত স্কিমা সহ প্রোটোবাফের একটি টেক্সটফরম্যাট ব্যবহার করে:
// 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++) বা স্ট্যাটিক ফাইনাল ক্লাস (জাভা) তৈরি করতে ব্যবহৃত হয় যেখানে জেনারেট করা API গুলি রাখা হয়। উদাহরণস্বরূপ, com.android.sysprop.BuildProperties হবে নেমস্পেস com::android::sysprop::BuildProperties এবং জাভাতে com.android.sysprop প্যাকেজে BuildProperties ক্লাস। |
prop | সম্পত্তির তালিকা। |
Property
বার্তা ক্ষেত্রগুলির অর্থ নিম্নরূপ।
মাঠ | অর্থ |
---|---|
api_name | উৎপন্ন API এর নাম। |
type | এই সম্পত্তির ধরন. |
access | Readonly : শুধুমাত্র গেটার API তৈরি করেWriteonce , ReadWrite : গেটার এবং সেটার API তৈরি করেদ্রষ্টব্য: উপসর্গ ro. ReadWrite অ্যাক্সেস ব্যবহার নাও করতে পারে। |
scope | Internal : শুধুমাত্র মালিক অ্যাক্সেস করতে পারেন।Public : NDK মডিউল ব্যতীত সবাই অ্যাক্সেস করতে পারে। |
prop_name | অন্তর্নিহিত সিস্টেম সম্পত্তির নাম, উদাহরণস্বরূপ ro.build.date । |
enum_values | ( Enum , শুধুমাত্র EnumList ) একটি বার(|)-বিচ্ছিন্ন স্ট্রিং যা সম্ভাব্য enum মান নিয়ে গঠিত। উদাহরণস্বরূপ, value1|value2 । |
integer_as_bool | ( Boolean , শুধুমাত্র BooleanList ) সেটারগুলিকে false এবং true পরিবর্তে 0 এবং 1 ব্যবহার করুন। |
legacy_prop_name | (ঐচ্ছিক, শুধুমাত্র Readonly বৈশিষ্ট্য) অন্তর্নিহিত সিস্টেম সম্পত্তির উত্তরাধিকার নাম। গেটারকে কল করার সময়, getter API prop_name পড়ার চেষ্টা করে এবং যদি prop_name বিদ্যমান না থাকে তাহলে legacy_prop_name ব্যবহার করে। একটি বিদ্যমান সম্পত্তিকে অবমূল্যায়ন করার সময় এবং একটি নতুন সম্পত্তিতে যাওয়ার সময় legacy_prop_name ব্যবহার করুন। |
প্রতিটি ধরনের সম্পত্তি C++, Java, এবং Rust-এ নিম্নলিখিত ধরনের মানচিত্র করে।
টাইপ | সি++ | জাভা | মরিচা |
---|---|---|---|
বুলিয়ান | std::optional<bool> | Optional<Boolean> | bool |
পূর্ণসংখ্যা | std::optional<std::int32_t> | Optional<Integer> | i32 |
UInt | 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 |
টি তালিকা | 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-এর জন্য API হিসেবে কাজ করে। বিল্ড সিস্টেম অভ্যন্তরীণভাবে 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 তালিকা ফাইল অন্তর্ভুক্ত করতে হবে। এটি করার জন্য, API ফাইল এবং একটি api
ডিরেক্টরি তৈরি করুন। api
ডিরেক্টরিটি Android.bp
মতো একই ডিরেক্টরিতে রাখুন। API ফাইলের নাম হল <module_name>-current.txt
, <module_name>-latest.txt
। <module_name>-current.txt
বর্তমান সোর্স কোডের API স্বাক্ষর ধারণ করে, এবং <module_name>-latest.txt
সর্বশেষ হিমায়িত API স্বাক্ষর ধারণ করে। বিল্ড সিস্টেম বিল্ড টাইমে জেনারেট করা API ফাইলগুলির সাথে এই API ফাইলগুলির তুলনা করে APIগুলি পরিবর্তন করা হয়েছে কিনা তা পরীক্ষা করে এবং একটি ত্রুটি বার্তা এবং current.txt
ফাইল আপডেট করার জন্য নির্দেশাবলী প্রকাশ করে যদি current.txt
সোর্স কোডগুলির সাথে মেলে না। এখানে একটি উদাহরণ ডিরেক্টরি এবং ফাইল সংস্থা:
├── api
│ ├── PlatformProperties-current.txt
│ └── PlatformProperties-latest.txt
└── Android.bp
মরিচা, জাভা এবং C++ ক্লায়েন্ট মডিউলগুলি জেনারেটেড API ব্যবহার করতে sysprop_library
সাথে লিঙ্ক করতে পারে। বিল্ড সিস্টেম ক্লায়েন্টদের থেকে জেনারেট করা C++, জাভা এবং রাস্ট লাইব্রেরিতে লিঙ্ক তৈরি করে, এইভাবে ক্লায়েন্টদের জেনারেট করা API-তে অ্যাক্সেস দেয়।
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"],
}
মনে রাখবেন যে মরিচা লাইব্রেরি নামটি 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);
}
…
}
জাভা উদাহরণ:
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);
}
…
}
…