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

تتبّع أداة Watchdog استخدام ذاكرة الفلاش من خلال تتبُّع إجمالي عدد عمليات النسخ المكتوبة للإدخال/الإخراج على القرص التي أجرتها جميع التطبيقات والخدمات باستخدام إحصاءات الإدخال/الإخراج على القرص لكل معرّف مستخدم، والتي يعرضها "النواة" في الموقع "‎/proc/uid_io/stats". وعندما يتجاوز أحد التطبيقات أو الخدمات الحدّ الأقصى لاستخدام الإدخال/الإخراج على القرص، تتّخذ أداة Watchdog إجراءات بشأن التطبيق أو الخدمة. يتم تحديد الحدود القصوى لاستخدام موارد الإدخال/الإخراج على القرص والإجراء الذي يجب اتّخاذه عند استخدامها بشكل مفرط في إعدادات استخدام موارد الإدخال/الإخراج على القرص بشكل مفرط.

حدود الاستخدام المفرط

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

الإجراءات المفرطة

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

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

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

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

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

يعرِض Watchdog واجهات برمجة تطبيقات النظام من خلال CarWatchdogManager، ما يتيح لتطبيقات أو خدمات المورّدين تعديل إعدادات المورّد في أي وقت.

الإفراط في تعريف الإعدادات

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

إعدادات المورّد

تحدِّد إعدادات المورّد الحدود القصوى لاستخدام I/O على القرص والإجراءات المتعلّقة بها لجميع تطبيقات وخدمات المورّد، وجميع تطبيقات الخرائط والوسائط. يحتوي الإعداد على حقول الإعداد التالية.

  • بادئات حزمة المورّدين: تُعدّ جميع الحِزم المثبَّتة في ملف تعريف "المورّد" حِزم مورّد. بالإضافة إلى هذه الحِزم، يمكن للمورّدين تصنيف الحِزم المثبَّتة مسبقًا على أنّها حِزم مورّدين من خلال إضافة بادئات الحِزم إلى إعدادات بادئات حِزم المورّدين. لا تقبل هذه الإعدادات التعبيرات العادية.
  • الحِزم الآمنة للإيقاف: يمكن للمورّدين تحديد حِزم المورّدين التي يمكن إنهاءها بأمان من خلال إضافة أسماء الحِزم الكاملة إلى إعدادات الحِزم الآمنة لإنهائها.
  • عمليات ربط فئات التطبيقات يمكن للمورّدين ربط أي حزمة (بما في ذلك الحِزم التابعة لجهات خارجية) بواحدة من فئتَي التطبيقات المتوافقتَين، وهما تطبيقات الوسائط والتطبيقات المخصّصة للخرائط. يتم إجراء هذا الربط لمنح تطبيقات الوسائط والتطبيقات المخصّصة للخرائط حدودًا أعلى لاستخدام موارد الإدخال/الإخراج في القرص، لأنّ هذه التطبيقات تميل إلى تنزيل المزيد من البيانات وكتابتها على القرص مقارنةً بأنواع التطبيقات الأخرى.
  • الحدود الدنيا على مستوى المكوّن: تحدِّد هذه الحدود العامة لجميع حِزم المورّدين (أي الحِزم التي لا تندرج ضمن الحدود الخاصة بالحزمة أو الحدود الخاصة بفئة التطبيق تحصل على هذه الحدود). على المورّدين تحديد حدود قصوى غير صفرية على مستوى المكوّنات عند تحديد إعدادات الاستخدام المفرط لعملية إدخال/إخراج القرص.
  • الحدود الدنيا الخاصة بالحزمة يمكن للمورّدين تحديد حدود قياس خاصة لحِزم مورّدين معيّنة. ويجب أن تحتوي عمليات الربط على أسماء الحِزم الكاملة. تكون للحدود المحدّدة في هذا الإعداد الأولوية على الحدود المحدّدة في الإعدادات الأخرى لحزمة معيّنة.
  • الحدود الدنيا لفئة التطبيق: يمكن للمورّدين تحديدحدود دنيا خاصة لفئات تطبيقات معيّنة. يجب أن تكون فئات التطبيق من الفئات المتوافقة، أي تطبيقات "الخرائط" و"الوسائط" . يتمّ ربط الحدود الدنيا المحدّدة في هذه الإعدادات بحِزم محدّدة باستخدام عمليات ربط فئات التطبيقات.
  • الحدود الدنيا على مستوى النظام: على المورّدين عدم تحديد هذه الإعدادات.

لا يمكن تعديل إعدادات بادئات حِزم المورّدين والحِزم الآمنة للإيقاف والحدود القصوى على مستوى المكوّنات والحدود القصوى الخاصة بالحِزم إلا من خلال إعدادات المورّد ل تطبيقات المورّدين وخدماته. لا يمكن تعديل إعدادات حدود الاستهلاك الخاصة بفئة التطبيق إلا من خلال إعدادات المورّد لجميع تطبيقات الخرائط والوسائط.

تحتوي حدود الاستخدام المفرط على عدد البايتات المسموح بكتابتها خلال:

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

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

إعدادات النظام والإعدادات التابعة لجهات خارجية

على المصنّعين الأصليّين للأجهزة عدم تعديل إعدادات النظام والإعدادات التابعة لجهات خارجية.

  • تحدِّد إعدادات النظام حدود الاستخدام المفرط لعمليات الإدخال/الإخراج والإجراءات المتعلّقة بها لتطبيقات النظام وخدماته.
    • يمكن أن يؤدي هذا الضبط أيضًا إلى تعديل عمليات ربط فئة التطبيق. وبالتالي، تتم مشاركة حقل الإعدادات هذا بين إعدادات النظام والبائع.
  • تحدِّد عملية الضبط التابعة لجهة خارجية الحدود القصوى لجميع التطبيقات التابعة لجهات خارجية. كل التطبيقات التي لم يتم تثبيتها مسبقًا في النظام هي تطبيقات تابعة لجهات خارجية.
    • تتلقّى جميع التطبيقات التابعة لجهات خارجية الحدود الدنيا نفسها (على سبيل المثال، لا يتلقّى أي تطبيق تابع لجهة خارجية حدودًا الدنيا خاصة) باستثناء تطبيقات الوسائط والخرائط، التي يتم تحديد حدودها الدنيا من خلال إعدادات المورّد.
    • إنّ الحدود الدنيا التلقائية المدرَجة أدناه لتجاوز استخدام وحدات الإدخال والإخراج للقرص هي الحدود التلقائية للتطبيقات التابعة لجهات خارجية. يتم شحن هذه الحدود مع صورة النظام.
      • ‫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 لضبط الإعدادات الجديدة.
  • للحصول على إعدادات الاستخدام المفرط لعملية I/O على القرص وضبطها، استخدِم العلامة 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();
}

التطبيقات التي تتحقّق من الإفراط في استخدام الموارد

يمكن للمورّدين والتطبيقات التابعة لجهات خارجية الاستماع إلى إشعارات حول الإفراط في استخدام الموارد الخاصة بالتطبيق من مراقب النظام أو الاستطلاع CarWatchdogManager لمعرفة إحصاءات الإفراط في استخدام الموارد الخاصة بالتطبيق على مدار آخر 30 يومًا.

الاستماع إلى إشعارات الاستخدام المفرط للموارد

يمكن للتطبيقات تنفيذ مستمع لاستخدام الموارد الزائد وتسجيله مع CarWatchdogManager لتلقّي إشعارات خاصة بالتطبيق عند تجاوزه الحدود القصوى لاستخدام موارد الإدخال/الإخراج في القرص بنسبة% 80 أو% 100. يمكن للتطبيقات استخدام هذه الإشعارات لإجراء ما يلي:

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

برنامج Java العميل

  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 المتعلّقة باستخدام I/O المفرط المخصّصة للتطبيق خلال آخر 30 يومًا.

عميل Java

استخدِم CarWatchdogManager.getResourceOveruseStats للاطّلاع على إحصاءات الاستخدام المفرط للموارد. نقْل العلامة CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO للحصول على إحصاءات الاستخدام المفرط لعمليات I/O على القرص.

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) باستخدام 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 من "CDD [C-1-1]".

التطبيقات التي تؤثر في الأداء

الشكل 1: التطبيقات التي تؤثر في الأداء

يتم هنا إدراج التطبيقات التي تم إنهاؤها بسبب الإفراط في استخدام الموارد (راجِع الشكل 2). يمكن منح الأولوية للتطبيقات المدرَجة. لمزيد من المعلومات، اطّلِع على منح الأولوية لأداء التطبيق.

قائمة التطبيقات التي تم إغلاقها بسبب الإفراط في استخدام الموارد

الشكل 2. قائمة التطبيقات التي تم إغلاقها بسبب الإفراط في استخدام الموارد

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

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

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

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

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

اقتراح بشأن تنفيذ مشغّل التطبيقات

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

إصدار Android SC V2