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

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

ספי שימוש יתר

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

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

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

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

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

תצורת שימוש יתר

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

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

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

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

תצורת ספק

תצורת הספק מגדירה את הספים והפעולות של שימוש יתר ב-I/O בדיסק עבור כל האפליקציות והשירותים של הספק, וכל אפליקציות המפות והמדיה. התצורה מכילה את שדות התצורה שלהלן.

  • Vendor package prefixes . כל החבילות המותקנות במחיצת הספק נחשבות כחבילות ספק. בנוסף לחבילות אלו, ספקים יכולים לסווג חבילות מותקנות מראש כחבילות ספק על ידי הוספת קידומות החבילה לתצורת vendor package prefixes . תצורה זו אינה מקבלת ביטויים רגולריים.
  • Safe-to-terminate packages . ספקים יכולים לציין אילו חבילות ספקים בטוחות להסתיים על ידי הוספת שמות החבילות המלאים לתצורת safe-to-terminate packages .
  • Application category mappings . ספקים יכולים למפות כל חבילה (כולל חבילות של צד שלישי) לאחת משתי קטגוריות האפליקציות הנתמכות - אפליקציות מפה ומדיה. מיפוי זה נעשה כדי לספק למפות ואפליקציות מדיה ספי שימוש יתר בדיסק I/O גבוהים יותר מכיוון שאפליקציות אלו נוטות להוריד ולכתוב יותר נתונים לדיסק מאשר סוגי אפליקציות אחרים.
  • Component level thresholds . מגדיר ספים גנריים עבור כל חבילות הספק (כלומר, חבילות שאינן מכוסות Package specific thresholds או Application category specific thresholds מקבלים את הספים הללו). הספקים חייבים להגדיר ספים שאינם אפס ברמת הרכיב בעת הגדרת תצורת שימוש יתר בדיסק I/O.
  • 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 רק על ידי תצורת הספק עבור כל אפליקציות המפות והמדיה.

ספי השימוש המופרז מכילים את כמות הבתים המותרת להיכתב במהלך

  • מצב קדמה של אפליקציה/שירות מול מצב רקע
  • ומצב מוסך מערכת.

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

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

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

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

שימוש יתר בתבנית XML

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

קובץ ה-XML צריך להכיל רק תג אחד עבור כל שדה תצורה. יש להגדיר תצורת שימוש יתר ב-I/O בקובץ ה-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. יישם מאזין על ידי ירושה של 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 (מאקרו 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. התחל מאגר שרשורי קלסר ורשום את המאזין לשימוש יתר במשאבים בשרת ה-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 ספציפי לאפליקציה עבור 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 enum כדי להביא נתונים סטטיסטיים של שימוש יתר בדיסק I/O.

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>

הודעת משתמש

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

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

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

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

המלצה ליישום משגר

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

שחרור אנדרואיד SC V2