מעקב אחר השימוש בזיכרון ה-Flash

Watchdog עוקב אחר השימוש בזיכרון Flash על ידי מעקב אחר הכמות הכוללת של קלט/פלט בדיסק כתיבה על ידי כל האפליקציות והשירותים באמצעות נתוני קלט/פלט (I/O) של דיסק לפי UID נחשפו על ידי הליבה במיקום '/proc/uid_io/stats'. כשאפליקציה או השירות חורגים מסף שימוש היתר של קלט/פלט בדיסק, ה-Watchdog נוקט פעולות באפליקציה או בשירות. ערכי הסף של הקלט/פלט (I/O) והפעולה שצריך לבצע onuse (שימוש יתר) מוגדר מראש בתצורה של שימוש יתר בקלט/פלט (I/O) בדיסק.

ערכי סף של שימוש יתר

  • ערכי הסף לשימוש יתר בדיסקים נאכפים על בסיס יומי, כלומר כל שנכתבו על ידי אפליקציה או שירות נצברים מאז היום הקלנדרי הנוכחי לפי שעון UTC, ונבדק מול ערכי הסף שהוגדרו שימוש יתר בתצורות.
  • כשרכב מופעל כמה פעמים ביום נתון, המודול של הטיימר המפקח (watchdog) מאחסן את נתוני השימוש של קלט/פלט בדיסק בזיכרון ה-Flash וצובר אותם מאז תחילת היום הקלנדרי הנוכחי לפי שעון UTC.

פעולות של שימוש יתר

כשאפליקציה חורגת שוב ושוב משימוש היתר בקלט/פלט בדיסק וספים נוספים, Watchdog נוקט פעולות שהוגדרו בתצורה של שימוש יתר.

  • כל האפליקציות והשירותים של הספקים נחשבים קריטיים את היציבות הכוללת של המערכת, כך שהן לא מסתיימות בשימוש יתר בקלט/פלט בדיסק. אבל, לפעמים הגדרת שימוש יתר יכולה להגדיר רשימה של אפליקציות ספק בטוחות למחיקה ושירותים.
  • כל האפליקציות של צד שלישי בטוחות לגמרי.

כאשר אפליקציה או שירות בטוחים לסיום, Watchdog משבית את האפליקציה או את השירות באמצעות האפליקציה מצב הרכיב PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED

הגדרות של שימוש יתר

תצורת שימוש יתר מכילה את ערכי הסף לשימוש יתר בדיסק של קלט/פלט (I/O) וגם פעולות. הגדרות ברירת המחדל של שימוש יתר מוגדרות במערכת ובספק תמונות ונשלחות יחד עם ה-build. ספקים יכולים לכלול את הספק באופן אופציונלי את התצורה שלו בתמונת הספק. כשהגדרת הספק לא הגדרות המערכת משמשות את האפליקציות של הספקים שירותי Google גם כן.

Watchdog חושף את ממשקי ה-API של המערכת באמצעות CarWatchdogManager, וכך מאפשר אפליקציות או שירותים של ספקים מעדכנים את הגדרות הספק בכל שלב.

הגדרת תצורה של שימוש יתר

ההגדרות של שימוש יתר מחולקות לפי סוג הרכיב. לדוגמה: מערכת, ספק וצד שלישי. יצרני ציוד מקורי חייבים לעדכן רק את התצורה של הרכיב של הספק.

הגדרת הספק

הגדרת הספק מגדירה את ערכי הסף והפעולות של קלט/פלט בדיסק עבור את כל האפליקציות והשירותים של הספקים, ואת כל אפליקציות המפות והמדיה. ההגדרה האישית מכילה את שדות ההגדרה הבאים.

  • קידומות של חבילות של ספקים. כל החבילות שמותקנות ב חלוקת ספקים נחשבת כחבילות של ספקים. נוסף לשבעת חבילות, ספקים יכולים לסווג חבילות שהותקנו מראש כחבילות ספק לפי הוספת הקידומות של החבילות להגדרה של קידומות של חבילות ספק. ההגדרה הזו לא מקבלת ביטויים רגולריים.
  • חבילות בטוחות למחיקה. ספקים יכולים לציין איזה ספק אפשר לסיים חבילות באופן בטוח על ידי הוספת השמות המלאים של החבילות הגדרת חבילות בטוחות לסיום.
  • מיפויים של קטגוריות אפליקציות. ספקים יכולים למפות כל חבילה (כולל חבילות של צד שלישי) לאחת משתי האפליקציות הנתמכות קטגוריות - אפליקציות מפות ומדיה. המיפוי הזה נועד לספק מפות ואפליקציות מדיה גבוהות יותר בערכי סף של קלט/פלט (I/O) בדיסק, כי אפליקציות נוטות להוריד ולכתוב לדיסק יותר נתונים מאשר אפליקציות אחרות שונים.
  • ערכי סף ברמת הרכיב. הגדרת ערכי סף כלליים לכולם חבילות של ספק (כלומר, חבילות שאינן מכוסות על ידי חבילה ספציפית ערכי סף מסוימים או ערכי סף ספציפיים לקטגוריית אפליקציות סכומי הסף האלה). הספקים חייבים להגדיר ערכי סף שאינם אפס ברמת הרכיבים, כאשר הגדרה של תצורת שימוש יתר בקלט/פלט בדיסק.
  • ערכי סף ספציפיים לחבילה. הספקים יכולים להגדיר וערכי סף לחבילות ספציפיות של ספקים. המיפויים צריכים להכיל את הפרמטר שמות מלאים של חבילות. ערכי הסף שהוגדרו בהגדרה הזו מקבלים עדיפות מעל ערכי הסף שמוגדרים בתצורה אחרת לחבילה נתונה.
  • ערכי סף ספציפיים לקטגוריות של אפליקציות. הספקים יכולים לציין דרישות סף מיוחדות לקטגוריות ספציפיות של אפליקציות. האפליקציה הקטגוריות חייבות להיות אחת מהקטגוריות הנתמכות – מפות ומדיה תרגום מכונה. ערכי הסף שמוגדרים בהגדרה הזו ממופים באמצעות מיפויים של קטגוריות אפליקציות.
  • ערכי סף ברמת המערכת. אסור לספקים לציין את ההגדרה הזו.

קידומות של חבילות של ספקים, חבילות בטוחות לסגירה, ערכי סף ברמת הרכיב וספציפי לחבילה את הגדרות הסף אפשר לעדכן רק על ידי הגדרת הספק האפליקציות והשירותים של הספקים. ספציפי לקטגוריית אפליקציה את הגדרות הסף אפשר לעדכן רק על ידי הגדרת הספק עבור כל מפות ואפליקציות מדיה.

ערכי הסף של שימוש יתר מכילים את כמות הבייטים שמותר לכתוב במהלך:

  • מצב חזית של אפליקציה או שירות לעומת מצב רקע
  • מצב החניה של המערכת

הסיווג הזה מאפשר לאפליקציות ולשירותים שפועלים בחזית וגלויים למשתמשים: לכתוב יותר נתונים מאשר אפליקציות ושירותים שפועלים ברקע. במצב חנייה, אפליקציות ושירותים נוטים להוריד עדכונים, כך שלכל אחד מהם נדרש סף גבוה יותר מאשר אפליקציות ושירותים שפועלים במצבים אחרים.

הגדרות של מערכת וצד שלישי

יצרני ציוד מקורי לא אמורים לעדכן את הגדרות המערכת ואת הגדרות הצד השלישי.

  • הגדרת המערכת מגדירה ערכי סף של שימוש יתר בקלט/פלט (I/O) ופעולות עבור אפליקציות ושירותים של המערכת.
    • התצורה הזו יכולה גם לעדכן את קטגוריית האפליקציות מיפויים. לכן, שדה ההגדרה הזה משותף בין המערכת לספק הגדרות אישיות.
  • הגדרות אישיות של צד שלישי מגדירות ערכי סף לכל צד שלישי תרגום מכונה. כל האפליקציות שלא מותקנות מראש במערכת אפליקציות צד שלישי.
    • כל האפליקציות של צד שלישי מקבלות את אותם ערכי סף (לדוגמה, אפליקציית צד שלישי מקבלת ערכי סף מיוחדים) מלבד מפות ומדיה אפליקציות, שהספים שלהן מוגדרים על ידי תצורת הספק.
    • ערכי הסף הבאים של קלט/פלט (I/O) בדיסק הם ערכי הסף שמוגדרים כברירת מחדל אפליקציות צד שלישי. ערכי הסף האלה נשלחים יחד עם תמונת המערכת.
      • 3 כתיבה ב-GiB במצב חזית האפליקציה.
      • כתיבה של 2 GiB במצב ברקע של האפליקציה.
      • כתיבה של 4 GiB במצב החניה של המערכת.
    • אלה ערכי סף בסיסיים. ערכי הסף האלה מתעדכנים ככל שנלמד יותר על הקלט/פלט של הדיסק בשימוש.

פורמט XML של הגדרת שימוש יתר

אפשר לקבוע את הגדרת ברירת המחדל של הספק (אופציונלי) במיקום עצמו /vendor/etc/automotive/watchdog/resource_overuse_configuration.xml בקובץ האימג' של ה-build. כאשר התצורה הזו לא מוגדרת, המערכת תיושם גם על אפליקציות ושירותים של ספקים.

קובץ ה-XML צריך להכיל תג אחד בלבד לכל שדה config. שימוש יתר בקלט/פלט יש להגדיר אותן בקובץ ה-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>

עדכון ההגדרה של שימוש יתר באמצעות ממשקי API של המערכת של CarWatchdogManager

אפשר לספק את תצורת ה-XML שלמעלה רק בקובץ האימג' של ה-build. אם ה-OEM (יצרן הציוד המקורי) בוחר לעדכן את התצורה במכשיר לאחר פרסום גרסת ה-build, הם יכולים להשתמש בממשקי ה-API הבאים כדי לבצע שינויים בהגדרות במכשיר.

  • נותנים את ההרשאה 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% מערכי הסף של קלט/פלט (I/O) בדיסק. אפליקציות יכולות להשתמש התראות אלה כדי:

  • מתעדים את הנתונים הסטטיסטיים של שימוש יתר בדיסק לצורך ניתוח אופליין. אפליקציה מפתחים יכולים להשתמש ברישום הזה ביומן כדי לנפות באגים בבעיה של שימוש יתר בקלט/פלט (I/O).
  • מצמצמים את פעולות הכתיבה של הקלט/פלט בדיסק עד לאיפוס מוני השימוש יתר.

לקוח Java

  1. הטמעת ה-listener על ידי קבלת בירושה של 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. רישום המופע של ה-listener באמצעות קריאה 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. ביטול הרישום של מופע ה-listener כשהאפליקציה מסיימת להאזין ל:
    private void removeResourceOveruseListener() {
        CarWatchdogManager manager =
                (CarWatchdogManager) car.getCarManager(Car.CAR_WATCHDOG_SERVICE);
        mCarWatchdogManager.removeResourceOveruseListener(
              mListenerImpl);
    }
    

Native Client

  1. כלול את carwatchdog_aidl_interface-ndk_platform ב התלות של shared_libs בכלל ה-build.

    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 (מאקרו 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. הטמעה של ה-listener לשימוש יתר במשאבים על ידי קבלת בירושה 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. יצירת מאגר שרשורים של binder ורישום של ה-listener לשימוש יתר במשאבים באמצעות שרת ה-watchdog. שרת ה-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 את שימוש היתר בקלט/פלט (I/O) ספציפי לאפליקציה ATS עבור 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()
}

Native Client

שימוש ב-CarWatchdogServer.getResourceOveruseStats כדי לקבל נתונים סטטיסטיים של שימוש יתר במשאבים. מעבירים את ה-enum 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). כשמקישים עליה, מופיעה רשימה של אפליקציות שהגישה אליהן הוגבלה בגלל זיכרון ה-Flash מוצגים נתונים של שימוש יתר ושמשפיעים לרעה על ביצועי המערכת. אחרי דרישה של CDD 3.5.1 [C-1-1].

אפליקציות שמשפיעות על הביצועים

איור 1. אפליקציות שמשפיעות על הביצועים.

אפליקציות שנסגרו עקב שימוש יתר במשאבים מפורטות כאן (ראו איור 2). האפליקציות ברשימה יכולות לקבל עדיפות. מידע נוסף זמין במאמר הבא: קביעת עדיפות להגדרה של ביצועי האפליקציות.

רשימת האפליקציות הופסקה בגלל שימוש יתר במשאבים

איור 2. רשימת האפליקציות הסתיימה בגלל שימוש יתר במשאבים.

התראה למשתמש

כשאפליקציה או שירות משתמשים מדי פעם בקלט/פלט בדיסק (לדוגמה, כתיבה נתונים לדיסק מעבר לערכי הסף המוגדרים) במהלך תקופה מסוימת, והם בטוחים תופסק עקב שימוש יתר במשאבים, המשתמש יקבל הודעה לאחר שהרכב נכנס את מצב ההחרגה של מנהל התקן.

ההתראה הראשונה למשתמש (במהלך נסיעה) מופיעה כהתראה מראש ההתראה וההתראות האחרות מפורסמות בהתראה במרכז.

לדוגמה, כשאפליקציה משתמשת מדי פעם בקלט/פלט בדיסק שוב ושוב, המשתמש מקבל את הקוד ההתראה הבאה:

  • כשהמשתמש לוחץ על הלחצן אני רוצה לתת עדיפות לאפליקציה, דף ההגדרות של האפליקציה מופעל, והמשתמש יכול להפעיל או להשבית תעדוף ביצועי האפליקציות.
  • כשהמשתמש לוחץ על הלחצן השבתת האפליקציה, האפליקציה מושבתת עד שהמשתמש מפעיל את האפליקציה או מפעיל אותה דף ההגדרות.
  • באפליקציות שניתנות להסרה, הלחצן השבתת האפליקציה הוא הוחלף בלחצן הסרת האפליקציה. כשהמשתמש לוחץ על הלחצן הסרת האפליקציה, דף ההגדרות של האפליקציה מופעל, שממנו המשתמש יכול להסיר את האפליקציה.

המלצה להטמעת מרכז האפליקציות

כשאפליקציות מושבתות עקב שימוש יתר במשאבים, הן נעלמות כאפליקציית מרכז האפליקציות שמוגדרת כברירת מחדל כי CarService מעדכנת את האפליקציות המצב מופעל בתור PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED יצרני ציוד מקורי חייבים לעדכן את ההטמעה המובנית של מרכז האפליקציות כדי להציג את האפליקציות האלה בצורה חריגה. כדי שמשתמשים יוכלו להשתמש בהם במקרה הצורך. תוכלו לראות את ההמלצות הבאות, בהתאם לגרסת ה-build.

גרסת Android SC V2