مراقبة استخدام ذاكرة فلاش

تراقب الوكالة الدولية للطاقة استخدام ذاكرة الفلاش من خلال تتبع المقدار الإجمالي لعمليات كتابة الإدخال/الإخراج للقرص التي تتم بواسطة جميع التطبيقات والخدمات باستخدام إحصائيات الإدخال/الإخراج للقرص لكل UID التي يكشفها Kernel في الموقع `/proc/uid_io/stats`. عندما يتجاوز تطبيق أو خدمة حد الإفراط في استخدام الإدخال/الإخراج للقرص، تتخذ Watchdog إجراءات بشأن التطبيق أو الخدمة. تم تحديد عتبات الإفراط في استخدام الإدخال/الإخراج للقرص والإجراء الذي سيتم اتخاذه بشأن الاستخدام الزائد مسبقًا في تكوين الإفراط في استخدام الإدخال/الإخراج للقرص.

عتبات الإفراط في الاستخدام

  • يتم فرض حدود الإفراط في استخدام الإدخال/الإخراج للقرص على أساس يومي، أي أنه يتم تجميع كافة عمليات الكتابة التي يتم إجراؤها بواسطة تطبيق/خدمة منذ بداية يوم تقويم UTC الحالي ويتم فحصها مقابل الحدود المحددة في تكوينات الإفراط في الاستخدام.
  • عند تشغيل المركبة عدة مرات في يوم معين، تقوم وحدة Watchdog بتخزين إحصائيات استخدام الإدخال/الإخراج للقرص على ذاكرة فلاش وتجميعها منذ بداية يوم تقويم UTC الحالي.

إجراءات الإفراط في الاستخدام

عندما يتجاوز أحد التطبيقات حدود الإفراط في استخدام الإدخال/الإخراج للقرص بشكل متكرر، فإن Watchdog تتخذ الإجراءات المحددة في تكوين الإفراط في الاستخدام.

  • تعتبر جميع تطبيقات وخدمات البائعين ضرورية لاستقرار النظام بشكل عام، لذلك لا يتم إنهاؤها عند الإفراط في استخدام الإدخال/الإخراج على القرص. ومع ذلك، يمكن أن يحدد تكوين الإفراط في الاستخدام قائمة بتطبيقات وخدمات البائع التي يمكن إنهاؤها بشكل آمن.
  • جميع تطبيقات الطرف الثالث آمنة للإنهاء.

عندما يكون التطبيق أو الخدمة آمنة للإنهاء، تقوم Watchdog بتعطيل التطبيق أو الخدمة باستخدام حالة مكون التطبيق PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED .

الإفراط في استخدام التكوين

يحتوي تكوين الاستخدام الزائد على عتبات وإجراءات الاستخدام الزائد للإدخال/الإخراج للقرص. يتم تحديد تكوينات الاستخدام الزائد الافتراضية في صور النظام والبائعين، ويتم شحنها مع الإصدار. قد يقوم البائعون بشكل اختياري بتضمين تكوين البائع في صورة البائع. عندما لا يتم توفير تكوين البائع، يتم استخدام تكوين النظام لتطبيقات وخدمات البائع أيضًا.

تكشف Watchdog عن واجهات برمجة تطبيقات النظام عبر CarWatchdogManager ، والتي تسمح لتطبيقات أو خدمات البائعين بتحديث تكوين البائع في أي وقت.

الإفراط في تعريف التكوين

يتم تقسيم تكوين الاستخدام الزائد حسب نوع المكون. على سبيل المثال، النظام والمورد والطرف الثالث. يجب على مصنعي المعدات الأصلية تحديث تكوين مكون البائع فقط.

تكوين البائع

يحدد تكوين البائع عتبات وإجراءات الإفراط في استخدام الإدخال/الإخراج للقرص لجميع تطبيقات وخدمات البائع، وجميع الخرائط وتطبيقات الوسائط. يحتوي التكوين على حقول التكوين أدناه.

  • Vendor package prefixes . تعتبر كافة الحزم المثبتة في قسم البائع بمثابة حزم بائع. بالإضافة إلى هذه الحزم، قد يقوم البائعون بتصنيف الحزم المثبتة مسبقًا كحزم موردين عن طريق إضافة بادئات الحزمة إلى تكوين vendor package prefixes . هذا التكوين لا يقبل التعبيرات العادية.
  • Safe-to-terminate packages . يمكن للموردين تحديد حزم البائعين الآمنة للإنهاء عن طريق إضافة أسماء الحزم الكاملة إلى تكوين safe-to-terminate packages .
  • Application category mappings . يجوز للبائعين تعيين أي حزمة (بما في ذلك حزم الجهات الخارجية) لإحدى فئتي التطبيقات المدعومة - تطبيقات الخرائط والوسائط. يتم إجراء هذا التعيين لتوفير عتبات أعلى لاستخدام الإدخال/الإخراج للقرص للخرائط وتطبيقات الوسائط لأن هذه التطبيقات تميل إلى تنزيل وكتابة المزيد من البيانات على القرص مقارنة بأنواع التطبيقات الأخرى.
  • Component level thresholds . يحدد الحدود العامة لجميع حزم البائعين (على سبيل المثال، الحزم التي لا تغطيها Package specific thresholds أو Application category specific thresholds تحصل على هذه الحدود). يجب على البائعين تحديد عتبات مستوى المكونات غير الصفرية عند تحديد تكوين الإفراط في استخدام الإدخال/الإخراج للقرص.
  • Package specific thresholds . يجوز للبائعين تحديد عتبات خاصة لحزم بائعين محددين. يجب أن تحتوي التعيينات على أسماء الحزمة الكاملة. الحدود المحددة في هذا التكوين لها الأسبقية على الحدود المحددة في التكوينات الأخرى لحزمة معينة.
  • Application category specific thresholds . يجوز للموردين تحديد حدود خاصة لفئات تطبيقات محددة. يجب أن تكون فئات التطبيقات إحدى الفئات المدعومة - تطبيقات الخرائط والوسائط. يتم تعيين الحدود المحددة في هذا التكوين لحزم محددة باستخدام Application category mappings .
  • System-wide thresholds . يجب ألا يحدد البائعون هذا التكوين.

لا Vendor package prefixes Safe-to-terminate packages Component level thresholds Package specific thresholds إلا من خلال تكوين البائع لتطبيقات وخدمات البائع. لا يمكن تحديث تكوين Application category specific thresholds إلا من خلال تكوين البائع لجميع الخرائط وتطبيقات الوسائط.

تحتوي عتبات الإفراط في الاستخدام على مقدار البايتات المسموح بكتابتها أثناء

  • وضع المقدمة للتطبيق/الخدمة مقابل وضع الخلفية
  • ووضع مرآب النظام.

يسمح هذا التصنيف للمستخدم الذي يواجه التطبيقات/الخدمات الأمامية بكتابة بيانات أكثر من التطبيقات/الخدمات الخلفية. في وضع Garage، تميل التطبيقات والخدمات إلى تنزيل التحديثات، لذا يحتاج كل منها إلى حد أعلى من التطبيقات والخدمات التي تعمل في الأوضاع الأخرى.

تكوينات النظام والجهات الخارجية

يجب على مصنعي المعدات الأصلية عدم تحديث النظام وتكوينات الجهات الخارجية.

  • يحدد تكوين النظام عتبات الإفراط في استخدام الإدخال/الإخراج والإجراءات الخاصة بتطبيقات النظام وخدماته.
    • قد يقوم هذا التكوين أيضًا بتحديث Application category mappings . وبالتالي، تتم مشاركة حقل التكوين هذا بين تكوينات النظام والمورد.
  • يحدد تكوين الطرف الثالث الحدود القصوى لجميع تطبيقات الطرف الثالث. جميع التطبيقات التي لم يتم تثبيتها مسبقًا في النظام هي تطبيقات تابعة لجهات خارجية.
    • تتلقى جميع تطبيقات الطرف الثالث نفس الحدود (على سبيل المثال، لا يتلقى أي تطبيق تابع لجهة خارجية حدودًا خاصة) باستثناء الخرائط وتطبيقات الوسائط، التي يتم تحديد حدودها بواسطة تكوين البائع.
    • تعتبر عتبات الإفراط في استخدام الإدخال/الإخراج للقرص أدناه هي العتبات الافتراضية لتطبيقات الطرف الثالث. يتم شحن هذه العتبات مع صورة النظام.
      • 3GiB الكتابة في الوضع الأمامي للتطبيق.
      • 2GiB الكتابة في وضع خلفية التطبيق.
      • 4GiB الكتابة في وضع مرآب النظام.
    • العتبات المذكورة أعلاه هي عتبات أساسية. سيتم تحديث هذه الحدود عندما نفهم استخدام الإدخال/الإخراج للقرص بشكل أفضل.

الإفراط في استخدام تنسيق 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 أعلاه فقط في صورة البناء. إذا اختار OEM تحديث التكوين على الجهاز بعد إصدار الإصدار، فيمكنه استخدام واجهات برمجة التطبيقات التالية لإجراء تغييرات على التكوين على الجهاز.

  • منح الإذن Car.PERMISSION_CONTROL_CAR_WATCHDOG_CONFIG للمتصل.
  • يجب استخدام التكوينات الموجودة لتحديث التكوينات الجديدة وتعيينها. استخدم API CarWatchdogManager.getResourceOveruseConfigurations للحصول على التكوينات الحالية. إذا لم يتم استخدام التكوينات الموجودة، فسيتم استبدال كافة التكوينات (بما في ذلك تكوينات النظام والجهات الخارجية)، وهو أمر غير مستحسن.
  • قم بتحديث التكوينات الموجودة بتغييرات الدلتا وقم بتعيين التكوينات الجديدة. لا تقم بتحديث تكوينات النظام ومكونات الطرف الثالث.
  • استخدم API 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% من حدود الإفراط في استخدام الإدخال/الإخراج للقرص. يمكن للتطبيقات استخدام هذه الإشعارات من أجل:

  • قم بتسجيل إحصائيات الإفراط في استخدام الإدخال/الإخراج للقرص للتحليل في وضع عدم الاتصال. يمكن لمطوري التطبيقات استخدام هذا التسجيل لتصحيح مشكلة الإفراط في استخدام الإدخال/الإخراج للقرص.
  • قم بتقليل عمليات كتابة الإدخال/الإخراج على القرص حتى تتم إعادة تعيين عدادات الاستخدام الزائد.

عميل جافا

  1. تنفيذ المستمع عن طريق وراثة 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()
                }
          }
    }
    
  2. قم بتسجيل مثيل المستمع عن طريق الاتصال بـ 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);
    }
    
  3. قم بإلغاء تسجيل مثيل المستمع عندما ينتهي التطبيق من الاستماع إلى:
    private void removeResourceOveruseListener() {
        CarWatchdogManager manager =
                (CarWatchdogManager) car.getCarManager(Car.CAR_WATCHDOG_SERVICE);
        mCarWatchdogManager.removeResourceOveruseListener(
              mListenerImpl);
    }
    

زبون محلي

  1. قم بتضمين 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,
    }
    
  2. أضف سياسة SELinux للسماح لمجال خدمة البائع باستخدام الموثق ( 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
    
  3. قم بتنفيذ مستمع الإفراط في استخدام الموارد عن طريق وراثة 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();
    }
    
  4. ابدأ تجمع مؤشرات ترابط الموثق وقم بتسجيل مستمع الإفراط في استخدام الموارد مع خادم المراقبة. يتم تسجيل خادم الوكالة الدولية للطاقة تحت اسم الخدمة 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 يومًا.

عميل جافا

استخدم 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
      }
}

الإفراط في استخدام الموارد UX

إعطاء الأولوية لإعداد أداء التطبيق

تحتوي صفحة إعدادات التطبيق على Prioritize app performance (انظر الصورة أدناه)، والتي تسمح للمستخدم بإعطاء الأولوية لأداء التطبيق على النظام وأداء الأجهزة على المدى الطويل. يتوفر هذا الإعداد فقط للتطبيقات التي يمكن إنهاؤها بشكل آمن عند الإفراط في استخدام الموارد. وبخلاف ذلك، سيظهر هذا الإعداد باللون الرمادي. عند إيقاف تشغيل هذا الإعداد (الإعداد الافتراضي) لأحد التطبيقات، يمكن إنهاء التطبيق عند الإفراط في استخدام الموارد. وبخلاف ذلك، لا يتم إنهاء التطبيق عند الإفراط في استخدام الموارد.

عندما يقوم المستخدم بالتبديل على هذا الإعداد، يصف مربع حوار التأكيد التالي الآثار المترتبة على التبديل على الإعداد.

وبعد مرور 90 يومًا، تتم إعادة تعيين هذا الإعداد تلقائيًا إلى الوضع الافتراضي. يمكن تعديل حد اليوم باستخدام تطبيق تراكب RRO باستخدام 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>

إشعار المستخدم

عندما يقوم تطبيق أو خدمة بإفراط في استخدام الإدخال/الإخراج للقرص بشكل متكرر (على سبيل المثال، كتابة البيانات إلى القرص بما يتجاوز الحدود المحددة) خلال فترة معينة ويكون من الآمن إنهاؤها عند الإفراط في استخدام الموارد، يتم إعلام المستخدم بعد دخول السيارة إلى برنامج التشغيل المسموح به -حالة التشتت.

يتم نشر إشعار المستخدم الأول (أثناء القيادة) كإشعار تنبيه ويتم نشر الإشعارات الأخرى في مركز الإشعارات.

على سبيل المثال، عندما يقوم أحد التطبيقات بإفراط في استخدام الإدخال/الإخراج للقرص بشكل متكرر، يتلقى المستخدم الإشعار التالي:

  • عندما ينقر المستخدم على زر تحديد أولوية التطبيق ، يتم تشغيل صفحة إعدادات التطبيق، حيث يمكن للمستخدم التبديل بين تشغيل أو إيقاف تشغيل إعداد تحديد أولوية أداء التطبيق .
  • عندما ينقر المستخدم على زر تعطيل التطبيق ، يتم تعطيل التطبيق حتى يقوم المستخدم بتشغيل التطبيق أو تمكينه في صفحة إعدادات التطبيق.
  • بالنسبة للتطبيقات القابلة لإلغاء التثبيت، يتم استبدال زر تعطيل التطبيق بزر إلغاء تثبيت التطبيق . عندما ينقر المستخدم على زر إلغاء تثبيت التطبيق ، يتم تشغيل صفحة إعدادات التطبيق، والتي يمكن للمستخدم من خلالها إلغاء تثبيت التطبيق.

توصية لتنفيذ قاذفة

عند تعطيل التطبيقات بسبب الإفراط في استخدام الموارد، تختفي التطبيقات من تطبيق المشغل الافتراضي لأن CarService تقوم بتحديث الحالة الممكنة للتطبيقات باسم PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED . يجب على مصنعي المعدات الأصلية تحديث تطبيق المشغل المدمج لعرض هذه التطبيقات على أنها غير عادية، حتى يتمكن المستخدمون من استخدامها إذا لزم الأمر. راجع التوصيات التالية بناءً على إصدار البنية.

إصدار أندرويد SC V2