يراقب Watchdog استخدام ذاكرة الفلاش من خلال تتبُّع إجمالي عدد عمليات الكتابة للإدخال/الإخراج على القرص التي تجريها جميع التطبيقات والخدمات باستخدام إحصاءات الإدخال/الإخراج على القرص لكل معرّف UID التي يعرضها النواة في المسار /proc/uid_io/stats. وعندما يتجاوز تطبيق أو خدمة الحدّ الأقصى المسموح به لاستخدام الإدخال/الإخراج على القرص، يتّخذ Watchdog إجراءات بشأن التطبيق أو الخدمة. يتم تحديد حدود الإفراط في استخدام الإدخال/الإخراج على القرص والإجراء الذي يجب اتّخاذه عند الإفراط في الاستخدام مسبقًا في إعدادات الإفراط في استخدام الإدخال/الإخراج على القرص.
حدود الاستخدام المفرط
- يتم فرض حدود الإفراط في استخدام عمليات الإدخال والإخراج على القرص بشكل يومي، أي يتم تجميع جميع عمليات الكتابة التي يجريها تطبيق أو خدمة منذ بداية يوم التقويم الحالي بالتوقيت العالمي المنسَّق (UTC) والتحقّق منها مقارنةً بالحدود المحدّدة في إعدادات الإفراط في الاستخدام.
- عند تشغيل المركبة عدة مرات في يوم معيّن، يخزِّن وحدة Watchdog إحصاءات استخدام إدخال/إخراج القرص في ذاكرة الفلاش ويجمعها منذ بداية يوم التقويم الحالي بالتوقيت العالمي المتفق عليه.
إجراءات الإفراط في الاستخدام
عندما يتجاوز أحد التطبيقات بشكل متكرّر الحدود المحدّدة للاستخدام المفرط لعمليات الإدخال والإخراج على القرص، يتّخذ Watchdog الإجراءات المحدّدة في إعدادات الاستخدام المفرط.
- تُعدّ جميع تطبيقات وخدمات المورّدين ضرورية لاستقرار النظام بشكل عام، لذا لا يتم إيقافها عند الإفراط في استخدام عمليات الإدخال والإخراج على القرص. ومع ذلك، يمكن أن يحدّد إعداد الاستخدام المفرط قائمة بالتطبيقات والخدمات التابعة لمورّدين والتي يمكن إيقافها بأمان.
- جميع التطبيقات التابعة لجهات خارجية يمكن إيقافها بأمان.
عندما يكون التطبيق أو الخدمة آمنَين للإيقاف، يوقف Watchdog التطبيق أو الخدمة باستخدام حالة مكوّن التطبيق
PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
.
إعدادات الاستخدام المفرط
يحتوي إعداد الاستخدام المفرط على الحدود الدنيا والإجراءات الخاصة بالاستخدام المفرط لعمليات الإدخال/الإخراج على القرص. يتم تحديد إعدادات الاستخدام المفرط التلقائية في صور النظام والمورّد، ويتم شحنها مع الإصدار. يمكن للمورّدين تضمين إعدادات المورّد في صورة المورّد بشكل اختياري. في حال عدم توفير إعدادات المورّد، يتم استخدام إعدادات النظام لتطبيقات وخدمات المورّد أيضًا.
تعرض Watchdog واجهات برمجة تطبيقات النظام من خلال CarWatchdogManager
، ما يتيح لتطبيقات المورّدين أو خدماتهم تعديل إعدادات المورّد في أي وقت.
تعريف إعدادات الاستخدام المفرط
يتم تقسيم إعدادات الاستخدام المفرط حسب نوع المكوّن، مثل النظام والمورّد والجهة الخارجية. على المصنّعين الأصليين للأجهزة تعديل إعدادات مكوّن المورّد فقط.
إعدادات المورِّد
يحدّد إعداد المورّد الحدود الدنيا للاستخدام المفرط لعمليات الإدخال والإخراج على القرص والإجراءات المتّخذة في جميع تطبيقات وخدمات المورّد وجميع تطبيقات الخرائط والوسائط. يحتوي الإعداد على حقول الإعداد التالية.
- بادئات حِزم المورّدين تُعدّ جميع الحِزم المثبَّتة في قسم المورّد حِزمًا خاصة بالمورّد. بالإضافة إلى هذه الحِزم، يمكن للمورّدين تصنيف الحِزم المثبَّتة مسبقًا على أنّها حِزم مورّدين من خلال إضافة بادئات الحِزم إلى إعداد بادئات حِزم المورّدين. لا يقبل هذا الإعداد التعبيرات العادية.
- الحِزم التي يمكن إيقافها بأمان يمكن للمورّدين تحديد حِزم المورّدين التي يمكن إنهاؤها بأمان من خلال إضافة أسماء الحِزم الكاملة إلى إعداد الحِزم التي يمكن إنهاؤها بأمان.
- عمليات ربط فئات التطبيقات يمكن للمورّدين ربط أي حزمة (بما في ذلك حِزم الجهات الخارجية) بإحدى فئتَي التطبيقات المتوافقتَين، وهما تطبيقات الخرائط وتطبيقات الوسائط. يتم إجراء هذا الربط لتوفير حدود قصوى أعلى للاستخدام المفرط لعمليات الإدخال والإخراج على القرص في تطبيقات الخرائط والوسائط، لأنّ هذه التطبيقات تميل إلى تنزيل المزيد من البيانات وكتابتها على القرص مقارنةً بأنواع التطبيقات الأخرى.
- الحدود على مستوى المكوّن: تحدّد هذه السمة الحدود الدنيا العامة لجميع حِزم المورّدين (أي الحِزم التي لا تغطيها الحدود الدنيا الخاصة بالحِزم أو الحدود الدنيا الخاصة بفئة التطبيقات). يجب أن يحدّد المورّدون حدودًا دنيا غير صفرية على مستوى المكوّن عند تحديد إعدادات الاستخدام المفرط لإدخال/إخراج القرص.
- الحدود الدنيا الخاصة بالحزمة يمكن للمورّدين تحديد حدود خاصة لحِزم مورّدين معيّنة. يجب أن تحتوي عمليات الربط على أسماء الحِزم الكاملة. تحظى الحدود المحدّدة في ملف الإعداد هذا بالأولوية على الحدود المحدّدة في ملفات الإعداد الأخرى لحزمة معيّنة.
- حدود دنيا خاصة بفئة التطبيق يمكن للمورّدين تحديد حدود خاصة لفئات تطبيقات معيّنة. يجب أن تكون فئات التطبيق إحدى الفئات المتوافقة، أي تطبيقات "الخرائط" و"الوسائط". يتم ربط الحدود الدنيا المحدّدة في هذا الإعداد بحِزم معيّنة باستخدام عمليات ربط فئات التطبيقات.
- الحدود على مستوى النظام يجب ألا يحدّد المورّدون هذا الإعداد.
لا يمكن تعديل إعدادات بادئات حِزم المورِّد والحِزم التي يمكن إيقافها بأمان وحدود مستوى المكوّن وحدود الحِزم المحدّدة إلا من خلال إعدادات المورِّد لتطبيقات وخدمات المورِّد. لا يمكن تعديل إعدادات الحدود الدنيا الخاصة بفئة التطبيق إلا من خلال إعدادات المورّد لجميع تطبيقات الخرائط والوسائط.
تحتوي حدود الاستخدام المفرط على عدد وحدات البايت المسموح بكتابتها خلال:
- وضع المقدّمة مقابل وضع الخلفية في التطبيقات أو الخدمات
- وضع "مرآب النظام"
يسمح هذا التصنيف للتطبيقات والخدمات التي تعمل في المقدّمة والتي تتفاعل مع المستخدمين بكتابة بيانات أكثر من التطبيقات والخدمات التي تعمل في الخلفية. في "وضع الصيانة"، تميل التطبيقات والخدمات إلى تنزيل التحديثات، لذا يحتاج كل منها إلى حدّ أعلى من التطبيقات والخدمات التي تعمل في أوضاع أخرى.
إعدادات النظام والجهات الخارجية
على الشركات المصنّعة للأجهزة الأصلية عدم تعديل إعدادات النظام وإعدادات الجهات الخارجية.
- يحدّد إعداد النظام الحدود القصوى للاستخدام المفرط للإدخال/الإخراج والإجراءات الخاصة بتطبيقات وخدمات النظام.
- يمكن أن يؤدي هذا الإعداد أيضًا إلى تعديل عمليات الربط بين فئات التطبيقات. وبالتالي، تتم مشاركة حقل الإعداد هذا بين إعدادات النظام وإعدادات المورّد.
- تحدّد إعدادات الجهات الخارجية الحدود الدنيا لجميع التطبيقات التابعة لجهات خارجية. جميع التطبيقات غير المثبَّتة مسبقًا في النظام هي تطبيقات تابعة لجهات خارجية.
- تتلقّى جميع التطبيقات التابعة لجهات خارجية الحدود نفسها (على سبيل المثال، لا يتلقّى أي تطبيق تابع لجهة خارجية حدودًا خاصة)، باستثناء تطبيقات الخرائط والوسائط، التي يتم تحديد حدودها من خلال إعدادات المورّد.
- في ما يلي الحدود القصوى التلقائية للاستخدام المفرط لعمليات الإدخال/الإخراج على القرص في التطبيقات التابعة لجهات خارجية. يتم تضمين هذه الحدود الدنيا في صورة النظام.
- كتابة 3 غيغابايت في وضع المقدّمة في التطبيق
- كتابة 2 غيغابايت في وضع الخلفية للتطبيق
- كتابة 4 غيغابايت في وضع "مرآب النظام"
- هذه هي الحدود الدنيا الأساسية. ويتم تعديل هذه الحدود الدنيا عند توفّر معلومات إضافية حول استخدام عمليات الإدخال والإخراج على القرص.
تنسيق XML لإعدادات الاستخدام المفرط
يمكن وضع إعدادات المورّد التلقائية (وهذا اختياري) في الموقع
/vendor/etc/automotive/watchdog/resource_overuse_configuration.xml
في صورة الإصدار. في حال عدم تحديد هذا الإعداد، يتم تطبيق الإعدادات المحدّدة من النظام على تطبيقات وخدمات المورّدين أيضًا.
يجب أن يحتوي ملف XML على علامة واحدة فقط لكل حقل إعداد. يجب تحديد إعدادات الاستخدام المفرط للإدخال/الإخراج في ملف XML. يجب تحديد جميع قيم الحدود الدنيا بوحدة MiB.
في ما يلي مثال على إعداد XML:
<resourceOveruseConfiguration version="1.0"> <componentType>VENDOR</componentType> <!-- List of safe to kill vendor packages. --> <safeToKillPackages> <package>com.vendor.package.A</package> <package>com.vendor.package.B</package> </safeToKillPackages> <!-- List of vendor package prefixes. --> <vendorPackagePrefixes> <packagePrefix>com.vendor.package</packagePrefix> </vendorPackagePrefixes> <!-- List of unique package names to app category mappings. --> <packagesToAppCategoryTypes> <packageAppCategory type="MEDIA">com.vendor.package.A</packageAppCategory> <packageAppCategory type="MAPS">com.google.package.B</packageAppCategory> <packageAppCategory type="MEDIA">com.third.party.package.C</packageAppCategory> </packagesToAppCategoryTypes> <ioOveruseConfiguration> <!-- Thresholds in MiB for all vendor packages that don't have package specific thresholds. --> <componentLevelThresholds> <state id="foreground_mode">1024</state> <state id="background_mode">512</state> <state id="garage_mode">3072</state> </componentLevelThresholds> <packageSpecificThresholds> <!-- IDs must be unique --> <perStateThreshold id="com.vendor.package.C"> <state id="foreground_mode">400</state> <state id="background_mode">100</state> <state id="garage_mode">200</state> </perStateThreshold> <perStateThreshold id="com.vendor.package.D"> <state id="foreground_mode">1024</state> <state id="background_mode">500</state> <state id="garage_mode">2048</state> </perStateThreshold> </packageSpecificThresholds> <!-- Application category specific thresholds. --> <appCategorySpecificThresholds> <!-- One entry per supported application category --> <perStateThreshold id="MEDIA"> <state id="foreground_mode">600</state> <state id="background_mode">700</state> <state id="garage_mode">1024</state> </perStateThreshold> <perStateThreshold id="MAPS"> <state id="foreground_mode">800</state> <state id="background_mode">900</state> <state id="garage_mode">2048</state> </perStateThreshold> </appCategorySpecificThresholds> </ioOveruseConfiguration> </resourceOveruseConfiguration>
تعديل إعدادات الاستخدام المفرط من خلال واجهات برمجة تطبيقات نظام CarWatchdogManager
لا يمكن توفير إعدادات XML أعلاه إلا في صورة الإصدار. إذا اختارت الشركة المصنّعة للجهاز تعديل الإعدادات على الجهاز بعد إصدار إصدار، يمكنها استخدام واجهات برمجة التطبيقات التالية لإجراء تغييرات على الإعدادات على الجهاز.
- امنح الإذن
Car.PERMISSION_CONTROL_CAR_WATCHDOG_CONFIG
للمتصل. - يجب استخدام الإعدادات الحالية لتعديل الإعدادات الجديدة وضبطها. استخدِم واجهة برمجة التطبيقات
CarWatchdogManager.getResourceOveruseConfigurations
للحصول على عمليات الإعداد الحالية. في حال عدم استخدام الإعدادات الحالية، سيتم استبدال جميع الإعدادات (بما في ذلك إعدادات النظام والإعدادات التابعة لجهات خارجية)، وهو أمر لا يُنصح به. - عدِّل الإعدادات الحالية باستخدام التغييرات التفاضلية واضبط الإعدادات الجديدة. لا تعدِّل إعدادات النظام والمكوّنات التابعة لجهات خارجية.
- استخدِم واجهة برمجة التطبيقات
CarWatchdogManager.setResourceOveruseConfigurations
لضبط الإعدادات الجديدة. - للحصول على إعدادات الاستخدام المفرط لإدخال/إخراج القرص وضبطها، استخدِم العلامة
CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO
.
في ما يلي نموذج لتنفيذ عملية تعديل إعدادات الاستخدام المفرط للموارد:
void updateResourceOveruseConfigurations() { CarWatchdogManager manager = (CarWatchdogManager) car.getCarManager(Car.CAR_WATCHDOG_SERVICE); List<ResourceOveruseConfiguration> resourceOveruseConfigurations = manager.getResourceOveruseConfigurations( CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO); List<ResourceOveruseConfiguration> newResourceOveruseConfigurations = new List<>(); ResourceOveruseConfiguration vendorConfiguration; for(ResourceOveruseConfiguration config : resourceOveruseConfigurations) { // Do not update the configurations of the system and third-party component types. if (config.getComponentType() != ResourceOveruseConfiguration.COMPONENT_TYPE_VENDOR) { newResourceOveruseConfigurations.add(config); continue; } vendorConfiguration = config; } if (vendorConfiguration == null) { ResourceOveruseConfiguration.Builder vendorConfigBuilder = new ResourceOveruseConfiguration.Builder(); initializeConfig(vendorConfigBuilder); newResourceOveruseConfigurations.add(vendorConfigBuilder.build()); } else { ResourceOveruseConfiguration newVendorConfig = updateConfig(vendorConfiguration); newResourceOveruseConfigurations.add(newVendorConfig); } int result = manager.setResourceOveruseConfigurations( newResourceOveruseConfigurations, if (result != CarWatchdogManager.RETURN_CODE_SUCCESS) { // Failed to set the resource overuse configurations. } } /** Sets the delta between the old configuration and the new configuration. */ ResourceOveruseConfiguration updateConfig( ResourceOveruseConfiguration oldConfiguration) { // Replace com.vendor.package.A with com.vendor.package.B in the safe-to-kill list. List<String> safeToKillPackages = oldConfiguration.getSafeToKillPackages(); safeToKillPackages.remove("com.vendor.package.A"); safeToKillPackages.add("com.vendor.package.B"); ResourceOveruseConfiguration.Builder configBuilder = new ResourceOveruseConfiguration.Builder( oldConfiguration.getComponentType(), safeToKillPackages, oldConfiguration.getVendorPackagePrefixes(), oldConfiguration.getPackagesToAppCategoryTypes()); configBuilder.addVendorPackagePrefixes("com.vendor."); configBuilder.addPackagesToAppCategoryTypes("com.vendor.package.B", ResourceOveruseConfiguration.APPLICATION_CATEGORY_TYPE_MAPS); IoOveruseConfiguration oldIoConfiguration = oldConfiguration.getIoOveruseConfiguration(); IoOveruseConfiguration.Builder ioConfigBuilder = new IoOveruseConfiguration.Builder( oldIoConfiguration.getComponentLevelThresholds(), oldIoConfiguration.getPackageSpecificThresholds(), oldIoConfiguration.getAppCategorySpecificThresholds(), oldIoConfiguration.getSystemWideThresholds()); // Define the amount of bytes based on the flash memory specification, expected lifetime, // and estimated average amount of bytes written by a package during different modes. ioConfigBuilder.addPackageSpecificThresholds("com.vendor.package.B", new PerStateBytes(/* foregroundModeBytes= */ 2 * 1024 * 1024 * 1024, /* backgroundModeBytes= */ 500 * 1024 * 1024, /* garageModeBytes= */ 3 * 1024 * 1024 * 1024)); return configBuilder.setIoOveruseConfiguration(ioConfigBuilder.build()).build(); }
التطبيقات التي تراقب الإفراط في استخدام الموارد
يمكن للمورّدين والتطبيقات التابعة لجهات خارجية الاستماع إلى إشعارات الإفراط في استخدام الموارد الخاصة بالتطبيق من Watchdog أو طلب CarWatchdogManager
للحصول على إحصاءات الإفراط في استخدام الموارد الخاصة بالتطبيق لمدة تصل إلى آخر 30 يومًا.
الاستماع إلى إشعارات الإفراط في استخدام الموارد
يمكن للتطبيقات تنفيذ أداة معالجة الاستخدام المفرط للموارد وتسجيلها في CarWatchdogManager
لتلقّي إشعارات خاصة بالتطبيق عند تجاوزها% 80 أو% 100 من حدود الاستخدام المفرط لإدخال/إخراج البيانات على القرص. يمكن للتطبيقات استخدام هذه الإشعارات في ما يلي:
- تسجيل إحصاءات الإفراط في استخدام عمليات الإدخال والإخراج على القرص لتحليلها بلا إنترنت يمكن لمطوّري التطبيقات استخدام هذا التسجيل لتصحيح خطأ الإفراط في استخدام عمليات الإدخال والإخراج على القرص.
- قلِّل عمليات الكتابة على القرص I/O إلى أن تتم إعادة ضبط عدّادات الاستخدام المفرط.
برنامج Java
- نفِّذ أداة معالجة الأحداث من خلال الوراثة من
CarWatchdogManager.ResourceOveruseListener
:class ResourceOveruseListenerImpl implements CarWatchdogManager.ResourceOveruseListener { @Override public void onOveruse( @NonNull ResourceOveruseStats resourceOveruseStats) { // 1. Log/Upload resource overuse metrics. // 2. Reduce writes until the counters reset. IoOveruseStats ioOveruseStats = resourceOveruseStats.getIoOveruseStats(); // Stats period - [ioOveruseStats.getStartTime(), ioOveruseStats.getStartTime() // + ioOveruseStats.getDurationInSeconds()] // Total I/O overuses - ioOveruseStats.getTotalOveruses() // Total bytes written - ioOveruseStats.getTotalBytesWritten() // Remaining write bytes for the current UTC calendar day - // ioOveruseStats.getRemainingWriteBytes() } } }
- سجِّل مثيل أداة معالجة الحدث من خلال استدعاء
CarWatchdogManager.addResourceOveruseListener
private void addResourceOveruseListener() { CarWatchdogManager manager = (CarWatchdogManager) car.getCarManager(Car.CAR_WATCHDOG_SERVICE); // Choose a proper executor to handle resource overuse notifications. Executor executor = mContext.getMainExecutor(); manager.addResourceOveruseListener( executor, CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO, mListenerImpl); }
- إلغاء تسجيل مثيل أداة المعالجة عند انتهاء التطبيق من الاستماع إلى:
private void removeResourceOveruseListener() { CarWatchdogManager manager = (CarWatchdogManager) car.getCarManager(Car.CAR_WATCHDOG_SERVICE); mCarWatchdogManager.removeResourceOveruseListener( mListenerImpl); }
برنامج متوافق
- أدرِج
carwatchdog_aidl_interface-ndk_platform
في الاعتماديةshared_libs
لقاعدة الإنشاء.Android.bp
cc_binary { name: "sample_native_client", srcs: [ "src/*.cpp" ], shared_libs: [ "carwatchdog_aidl_interface-ndk_platform", "libbinder_ndk", ], vendor: true, }
- أضِف سياسة SELinux للسماح لنطاق خدمة المورّد باستخدام binder
(وحدة الماكرو
binder_user
) وأضِف نطاق خدمة المورّد إلىcarwatchdog
نطاق العميل(carwatchdog_client_domain macro)
. اطّلِع على الرمز أدناه لمعرفةsample_client.te
وfile_contexts
.sample_client.te
type sample_client, domain; type sample_client_exec, exec_type, file_type, vendor_file_type; carwatchdog_client_domain(sample_client) init_daemon_domain(sample_client) binder_use(sample_client)
file_contexts
/vendor/bin/sample_native_client u:object_r:sample_client_exec:s0
- نفِّذ أداة معالجة الاستخدام المفرط للموارد من خلال الوراثة من
BnResourceOveruseListener
. يمكنك تجاهلBnResourceOveruseListener::onOveruse
للتعامل مع الإشعارات بشأن الإفراط في استخدام الموارد.ResourceOveruseListenerImpl.h
class ResourceOveruseListenerImpl : public BnResourceOveruseListener { public: ndk::ScopedAStatus onOveruse( ResourceOveruseStats resourceOveruseStats) override; private: void initialize(); void terminate(); std::shared_ptr<ICarWatchdog> mWatchdogServer; std::shared_ptr<IResourceOveruseListener> mListener; }
ResourceOveruseListenerImpl.cpp
ndk::ScopedAStatus ResourceOveruseListenerImpl::onOveruse( ResourceOveruseStats resourceOveruseStats) { // 1. Log/Upload resource overuse metrics. // 2. Reduce writes until the counters reset. if (stats.getTag() != ResourceOveruseStats::ioOveruseStats) { // Received resourceOveruseStats doesn't contain I/O overuse stats. } const IoOveruseStats& ioOveruseStats = stats.get(); // Stats period - [ioOveruseStats.startTime, // ioOveruseStats.startTime + ioOveruseStats.durationInSeconds] // Total I/O overuses - ioOveruseStats.totalOveruses // Total bytes written - ioOveruseStats.writtenBytes // Remaining write bytes for the current UTC calendar day - // ioOveruseStats.remainingWriteBytes return ndk::ScopedAStatus::ok(); }
- ابدأ مجموعة سلاسل ربط وأضِف مستمعًا إلى خادم مراقبة الاستخدام المفرط للموارد. يتم تسجيل خادم Watchdog ضمن اسم الخدمة
android.automotive.watchdog.ICarWatchdog/default
.main.cpp
int main(int argc, char** argv) { ABinderProcess_setThreadPoolMaxThreadCount(1); ABinderProcess_startThreadPool(); std::shared_ptr<ResourceOveruseListenerImpl> listener = ndk::SharedRefBase::make<ResourceOveruseListenerImpl>(); // The listener is added in initialize(). listener->initialize(); ... Run service ... // The listener is removed in terminate(). listener->terminate(); }
ResourceOveruseListenerImpl.cpp
void ResourceOveruseListener::initialize() { ndk::SpAIBinder binder(AServiceManager_getService( "android.automotive.watchdog.ICarWatchdog/default")); std::shared_ptr<ICarWatchdog> server = ICarWatchdog::fromBinder(binder); mWatchdogServer = server; std::shared_ptr<IResourceOveruseListener> listener = IResourceOveruseListener::fromBinder(this->asBinder()); mWatchdogServer->addResourceOveruseListener( std::vector<int>{ResourceType.IO}, listener); mListener = listener; } void ResourceOveruseListener::terminate() { mWatchdogServer->removeResourceOveruseListener(mListener); }
إحصاءات فرط استخدام موارد الاستطلاع
يمكن للتطبيقات أن تطلب من CarWatchdogManager الحصول على إحصاءات ATS الخاصة بالإفراط في استخدام عمليات الإدخال والإخراج الخاصة بالتطبيق خلال آخر 30 يومًا.
برنامج Java
استخدِم CarWatchdogManager.getResourceOveruseStats
للحصول على إحصاءات الإفراط في استخدام الموارد. أدخِل العلامة CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO
للحصول على إحصاءات الإفراط في استخدام أقراص الإدخال/الإخراج.
private void getResourceOveruseStats() { CarWatchdogManager manager = (CarWatchdogManager) car.getCarManager(Car.CAR_WATCHDOG_SERVICE); // Returns resource overuse stats with I/O overuse stats for the past // 7 days. Stats are available for up to the past 30 days. ResourceOveruseStats resourceOveruseStats = mCarWatchdogManager.getResourceOveruseStats( CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO, CarWatchdogManager.STATS_PERIOD_PAST_7_DAYS); IoOveruseStats ioOveruseStats = resourceOveruseStats.getIoOveruseStats(); // Stats period - [ioOveruseStats.getStartTime(), ioOveruseStats.getStartTime() // + ioOveruseStats.getDurationInSeconds()] // Total I/O overuses - ioOveruseStats.getTotalOveruses() // Total bytes written - ioOveruseStats.getTotalBytesWritten() // Remaining write bytes for the UTC calendar day - // ioOveruseStats.getRemainingWriteBytes() }
برنامج متوافق
استخدِم CarWatchdogServer.getResourceOveruseStats
للحصول على إحصاءات الإفراط في استخدام الموارد. مرِّر تعداد ResourceType.IO
لجلب إحصاءات الاستخدام المفرط لعمليات الإدخال/الإخراج على القرص.
void getResourceOveruseStats() { ndk::SpAIBinder binder(AServiceManager_getService( "android.automotive.watchdog.ICarWatchdog/default")); std::shared_ptr<ICarWatchdog> server = ICarWatchdog::fromBinder(binder); // Returns the stats only for the current UTC calendar day. const std::vector<ResourceOveruseStats> resourceOveruseStats; ndk::ScopedAStatus status = server.getResourceOveruseStats( std::vector<int>{ResourceType.IO}, &resourceOveruseStats); if (!status.isOk()) { // Failed to get the resource overuse stats. return; } for (const auto& stats : resourceOveruseStats) { if (stats.getTag() != ResourceOveruseStats::ioOveruseStats) { continue; } const IoOveruseStats& ioOveruseStats = stats.get(); // Stats period - [ioOveruseStats.startTime, // ioOveruseStats.startTime + ioOveruseStats.durationInSeconds] // Total I/O overuses - ioOveruseStats.totalOveruses // Total bytes written - ioOveruseStats.writtenBytes // Remaining write bytes for the current UTC calendar day - // ioOveruseStats.remainingWriteBytes } }
تجربة المستخدم عند الإفراط في استخدام الموارد
توضّح الأقسام التالية تجربة المستخدم عند الإفراط في استخدام الموارد.
إعداد "منح الأولوية لأداء التطبيق"
تحتوي صفحة الإعدادات في التطبيق على إعداداتPrioritize app performance
(راجِع الصورة أدناه)، ما يتيح للمستخدمين تحديد أولوية أداء التطبيق على أداء النظام وأداء الأجهزة على المدى الطويل. لا يتوفّر هذا الإعداد إلا للتطبيقات التي يمكن إيقافها بأمان في حال الإفراط في استخدام الموارد. وفي ما عدا ذلك، يكون هذا الإعداد غير مفعَّل. عند إيقاف هذا الإعداد (الإعداد التلقائي) لأحد التطبيقات، يمكن إنهاء التطبيق في حال الإفراط في استخدام الموارد.
وفي حال عدم توفّرها، لن يتم إيقاف التطبيق عند الإفراط في استخدام الموارد.
عندما يفعّل المستخدم هذا الإعداد، يوضّح مربّع حوار التأكيد التالي الآثار المترتبة على تفعيل الإعداد:
بعد مرور 90 يومًا، تتم إعادة ضبط هذا الإعداد تلقائيًا على الإعداد التلقائي. يمكن تعديل الحدّ الأقصى لعدد الأيام باستخدام تطبيق RRO overlay، وذلك باستخدام watchdogUserPackageSettingsResetDays
، وبحد أقصى 180 يومًا. لمزيد من المعلومات، اطّلِع على
تغيير قيمة موارد التطبيق في وقت التشغيل. يمكن تضمين علامة التراكب التالية في AndroidManifest.xml
:
<overlay android:priority="<insert-value>" android:targetPackage="com.android.car.updatable" android:targetName="CarServiceCustomization" android:resourcesMap="@xml/overlays" />
في res/values/config.xml
:
<resources> <integer name="watchdogUserPackageSettingsResetDays">value</integer> </resources>
في res/xml/overlays.xml
:
<overlay> <item target="integer/watchdogUserPackageSettingsResetDays" value="@integer/watchdogUserPackageSettingsResetDays" /> </overlay>
إعداد "التطبيقات التي تؤثر في الأداء"
يحتوي تطبيق الإعدادات على قسم التطبيقات التي تؤثر في الأداء (راجِع الشكل 1). عند النقر عليها، يتم عرض قائمة بالتطبيقات التي تم حظرها بسبب الإفراط في استخدام ذاكرة الفلاش، ما يؤثر سلبًا في أداء النظام. ويتماشى ذلك مع متطلبات القسم 3.5.1 من مستند تعريف التوافق مع Android [C-1-1].
الشكل 1. التطبيقات التي تؤثر في الأداء
يتم إدراج التطبيقات التي تم إنهاؤها بسبب الإفراط في استخدام الموارد هنا (راجِع الشكل 2). يمكن تحديد أولويات التطبيقات المُدرَجة. لمزيد من المعلومات، يمكنك الاطّلاع على إعداد منح الأولوية لأداء التطبيق.
الشكل 2. قائمة التطبيقات التي تم إنهاؤها بسبب الإفراط في استخدام الموارد
إشعار المستخدم
عندما يفرط تطبيق أو خدمة في استخدام عمليات الإدخال والإخراج على القرص بشكل متكرر (على سبيل المثال، كتابة البيانات على القرص بما يتجاوز الحدود المحددة) خلال فترة زمنية معيّنة ويكون من الآمن إيقافهما بسبب الإفراط في استخدام الموارد، يتم إشعار المستخدم بعد أن تدخل السيارة في حالة السماح بتشتيت انتباه السائق.
يتم نشر أول إشعار للمستخدم (أثناء القيادة) كإشعار عائم، ويتم نشر الإشعارات الأخرى في مركز الإشعارات.
على سبيل المثال، عندما يفرط أحد التطبيقات في استخدام عمليات الإدخال والإخراج على القرص بشكل متكرر، يتلقّى المستخدم الإشعار التالي:
- عندما ينقر المستخدم على الزر تحديد أولوية التطبيق، يتم فتح صفحة إعدادات التطبيق، حيث يمكن للمستخدم تفعيل الإعداد تحديد أولوية أداء التطبيق أو إيقافه.
- عندما ينقر المستخدم على الزر إيقاف التطبيق، يتم إيقاف التطبيق إلى أن يشغّله المستخدم أو يفعّله في صفحة إعدادات التطبيق.
- بالنسبة إلى التطبيقات التي يمكن إلغاء تثبيتها، يتم استبدال الزر إيقاف التطبيق بالزر إلغاء تثبيت التطبيق. عندما ينقر المستخدم على الزر إلغاء تثبيت التطبيق، يتم فتح صفحة "الإعدادات" الخاصة بالتطبيق، ويمكن للمستخدم من خلالها إلغاء تثبيت التطبيق.
اقتراح بشأن تنفيذ مشغّل التطبيقات
عند إيقاف التطبيقات بسبب الإفراط في استخدام الموارد، تختفي التطبيقات من تطبيق مشغّل التطبيقات التلقائي لأنّ CarService تعدّل حالة تفعيل التطبيقات إلى PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
.
على الشركات المصنّعة للأجهزة الأصلية تعديل عملية تنفيذ مشغّل التطبيقات المدمج لعرض هذه التطبيقات كالمعتاد،
ليتمكّن المستخدمون من استخدامها عند الحاجة. اطّلِع على الاقتراحات التالية استنادًا إلى إصدار التصميم.
إصدار Android SC V2
- يجب أن يستخدم تنفيذ مشغّل التطبيقات العلامة
MATCH_DISABLED_UNTIL_USED_COMPONENTS
عند استرداد قائمة الحِزم التي سيتم عرضها على مشغّل التطبيقات. - عندما ينقر المستخدم على تطبيق في الحالة
PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
، يجب أن يفعّل تطبيق مشغّل التطبيقات التطبيق من خلال ضبط حالة التفعيل على النحو التالي: