ตรวจสอบการใช้งานหน่วยความจำแฟลช

Watchdog จะตรวจสอบการใช้งานหน่วยความจำแฟลชโดยติดตามปริมาณทั้งหมดของการเขียน I/O ของดิสก์ซึ่งสร้างโดยแอปและบริการทั้งหมดที่ใช้สถิติ I/O ของดิสก์ต่อ UID ที่ Kernel เห็นในตำแหน่ง "/proc/uid_io/stats" เมื่อแอปหรือบริการ ใช้เกินเกณฑ์ของ I/O บนดิสก์ I/O มากเกินไป ก็จะดำเนินการกับแอปหรือบริการ เกณฑ์การใช้งานดิสก์ 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 ของดิสก์มากเกินไป ระบบจะกำหนดค่าเริ่มต้นของการใช้งานมากเกินไปไว้ในอิมเมจระบบและอิมเมจผู้ให้บริการ และมาพร้อมกับบิลด์ ผู้ให้บริการจะรวมการกำหนดค่าของผู้ให้บริการไว้ในรูปภาพของผู้ให้บริการหรือไม่ก็ได้ เมื่อไม่ได้ระบุการกําหนดค่าของผู้ให้บริการ ระบบจะใช้การกําหนดค่าของระบบสําหรับแอปและบริการของผู้ให้บริการด้วย

Watchdog จะแสดง API ของระบบผ่าน CarWatchdogManager ซึ่งช่วยให้แอปหรือบริการของผู้ให้บริการอัปเดตการกำหนดค่าของผู้ให้บริการได้ทุกเมื่อ

ใช้คำจำกัดความของการกำหนดค่ามากเกินไป

การกําหนดค่าที่ใช้งานมากเกินไปจะแบ่งตามประเภทคอมโพเนนต์ เช่น ระบบ ผู้ให้บริการ และบุคคลที่สาม OEM ต้องอัปเดตเฉพาะการกำหนดค่าคอมโพเนนต์ของผู้ให้บริการเท่านั้น

การกำหนดค่าผู้ให้บริการ

การกำหนดค่าผู้ให้บริการจะเป็นตัวกำหนดเกณฑ์และการใช้งานดิสก์ I/O มากเกินไปสำหรับแอปและบริการของผู้ให้บริการทั้งหมด รวมถึงแอปแผนที่และแอปสื่อทั้งหมด การกําหนดค่าจะมีฟิลด์การกําหนดค่าด้านล่าง

  • คำนำหน้าแพ็กเกจของผู้ให้บริการ แพ็กเกจทั้งหมดที่ติดตั้งในพาร์ติชันของผู้ให้บริการจะถือว่าเป็นแพ็กเกจของผู้ให้บริการ นอกจากแพ็กเกจเหล่านี้แล้ว ผู้ให้บริการยังสามารถจัดประเภทแพ็กเกจที่ติดตั้งไว้ล่วงหน้าเป็นแพ็กเกจของผู้ให้บริการได้ด้วยการเพิ่มคำนำหน้าแพ็กเกจลงในการกำหนดค่าคำนำหน้าแพ็กเกจของผู้ให้บริการ การกําหนดค่านี้ไม่ยอมรับนิพจน์ทั่วไป
  • แพ็กเกจที่สิ้นสุดได้อย่างปลอดภัย ผู้ให้บริการสามารถระบุแพ็กเกจผู้ให้บริการที่จะยกเลิกการใช้งานได้อย่างปลอดภัยโดยเพิ่มชื่อแพ็กเกจที่สมบูรณ์ลงในการกำหนดค่าแพ็กเกจที่ปลอดภัยสำหรับการสิ้นสุดการใช้งาน
  • การแมปหมวดหมู่แอปพลิเคชัน ผู้ให้บริการจะแมปแพ็กเกจใดก็ได้ (รวมถึงแพ็กเกจของบุคคลที่สาม) กับหมวดหมู่แอป 1 ใน 2 หมวดหมู่ที่รองรับ ซึ่งได้แก่ แอปแผนที่และสื่อ การแมปนี้ทำขึ้นเพื่อให้แอปแผนที่และแอปสื่อมีเกณฑ์การใช้งาน I/O ของดิสก์ที่สูงกว่า เนื่องจากแอปเหล่านี้มีแนวโน้มที่จะดาวน์โหลดและเขียนข้อมูลลงในดิสก์มากกว่าแอปประเภทอื่นๆ
  • เกณฑ์ระดับคอมโพเนนต์ กําหนดเกณฑ์ทั่วไปสําหรับแพ็กเกจของผู้ให้บริการทั้งหมด (นั่นคือ แพ็กเกจที่ไม่อยู่ภายใต้เกณฑ์เฉพาะแพ็กเกจหรือเกณฑ์เฉพาะหมวดหมู่แอปพลิเคชันจะได้รับเกณฑ์เหล่านี้) ผู้ให้บริการต้องกำหนดเกณฑ์ระดับคอมโพเนนต์ที่ไม่ใช่ 0 เมื่อกำหนดค่าการใช้ I/O ของดิสก์มากเกินไป
  • เกณฑ์เฉพาะแพ็กเกจ ผู้ให้บริการสามารถกําหนดเกณฑ์พิเศษสําหรับแพ็กเกจของผู้ให้บริการที่เฉพาะเจาะจง การแมปควรมีชื่อแพ็กเกจที่สมบูรณ์ เกณฑ์ที่กําหนดในการกําหนดค่านี้จะมีความสำคัญเหนือกว่าเกณฑ์ที่กําหนดในการกําหนดค่าอื่นๆ สําหรับแพ็กเกจหนึ่งๆ
  • เกณฑ์เฉพาะหมวดหมู่แอปพลิเคชัน ผู้ให้บริการสามารถระบุเกณฑ์พิเศษสำหรับหมวดหมู่แอปที่เฉพาะเจาะจงได้ หมวดหมู่แอปต้องเป็นหนึ่งในหมวดหมู่ที่รองรับ ซึ่งได้แก่ แอปแผนที่และแอปสื่อ โดยระบบจะแมปเกณฑ์ที่กําหนดไว้ในการกําหนดค่านี้กับแพ็กเกจที่เฉพาะเจาะจงโดยใช้การแมปหมวดหมู่แอปพลิเคชัน
  • เกณฑ์ทั้งระบบ ผู้ให้บริการต้องไม่ระบุการกำหนดค่านี้

คำนำหน้าแพ็กเกจของผู้ให้บริการ แพ็กเกจที่ปลอดภัยต่อการสิ้นสุดการใช้งาน เกณฑ์ระดับคอมโพเนนต์ และเกณฑ์เฉพาะแพ็กเกจจะอัปเดตได้โดยการกำหนดค่าของผู้ให้บริการสำหรับแอปและบริการของผู้ให้บริการเท่านั้น การกำหนดค่าเกณฑ์เฉพาะหมวดหมู่แอปพลิเคชันจะอัปเดตได้เฉพาะจากการกําหนดค่าของผู้ให้บริการสําหรับแอปแผนที่และแอปสื่อทั้งหมด

เกณฑ์การใช้งานมากเกินไปคือจำนวนไบต์ที่อนุญาตให้เขียนได้ในระหว่างช่วงเวลาต่อไปนี้

  • โหมดเบื้องหน้าของแอปหรือบริการเทียบกับโหมดเบื้องหลัง
  • โหมดโรงรถของระบบ

การจัดประเภทนี้ช่วยให้แอปและบริการที่แสดงอยู่เบื้องหน้าซึ่งแสดงต่อผู้ใช้เขียนข้อมูลได้มากกว่าแอปและบริการที่ทำงานอยู่เบื้องหลัง ในโหมดโรงรถ แอปและบริการมีแนวโน้มที่จะดาวน์โหลดการอัปเดต ดังนั้นแต่ละรายการจึงต้องมีเกณฑ์ที่สูงกว่าแอปและบริการที่ทำงานในโหมดอื่นๆ

การกําหนดค่าระบบและของบุคคลที่สาม

OEM ควรไม่อัปเดตระบบและการกําหนดค่าของบุคคลที่สาม

  • การกำหนดค่าระบบจะเป็นตัวกำหนดเกณฑ์และการดำเนินการ I/O มากเกินไปสำหรับแอปและบริการของระบบ
    • การกำหนดค่านี้อัปเดตการแมปหมวดหมู่แอปพลิเคชันได้ด้วย ดังนั้น ช่องการกําหนดค่านี้จะแชร์ระหว่างการกําหนดค่าระบบและผู้ให้บริการ
  • การกำหนดค่าของบุคคลที่สามจะกำหนดเกณฑ์สำหรับแอปของบุคคลที่สามทั้งหมด แอปทั้งหมดที่ไม่ได้ติดตั้งไว้ล่วงหน้าในระบบเป็นแอปของบุคคลที่สาม
    • แอปของบุคคลที่สามทั้งหมดจะมีเกณฑ์เดียวกัน (เช่น ไม่มีแอปของบุคคลที่สามใดได้รับเกณฑ์พิเศษ) ยกเว้นแอปแผนที่และแอปสื่อ ซึ่งเกณฑ์จะกำหนดโดยการกำหนดค่าของผู้ให้บริการ
    • เกณฑ์การใช้งานดิสก์ 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 ข้างต้นระบุได้ในอิมเมจบิลด์เท่านั้น หาก OEM เลือกที่จะอัปเดตการกำหนดค่าในอุปกรณ์หลังจากเผยแพร่บิลด์แล้ว ก็สามารถใช้ API ต่อไปนี้เพื่อทำการเปลี่ยนแปลงการกำหนดค่าในอุปกรณ์

  • ให้สิทธิ์ Car.PERMISSION_CONTROL_CAR_WATCHDOG_CONFIG แก่ผู้โทร
  • ต้องใช้การกำหนดค่าที่มีอยู่เพื่ออัปเดตและตั้งการกำหนดค่าใหม่ ใช้ API CarWatchdogManager.getResourceOveruseConfigurations เพื่อดูการกำหนดค่าที่มีอยู่ หากไม่ได้ใช้การกําหนดค่าที่มีอยู่ ระบบจะเขียนทับการกําหนดค่าทั้งหมด (รวมถึงการกําหนดค่าระบบและการกําหนดค่าของบุคคลที่สาม) ซึ่งเราไม่แนะนํา
  • อัปเดตการกําหนดค่าที่มีอยู่ด้วยการเปลี่ยนแปลง Delta และตั้งค่าการกําหนดค่าใหม่ อย่าอัปเดตการกำหนดค่าระบบและคอมโพเนนต์ของบุคคลที่สาม
  • ใช้ API CarWatchdogManager.setResourceOveruseConfigurations เพื่อตั้งค่าการกําหนดค่าใหม่
  • หากต้องการรับและตั้งค่าการกำหนดค่าการใช้งาน I/O ของดิสก์มากเกินไป ให้ใช้ Flag 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 วัน

ฟังการแจ้งเตือนการใช้งานทรัพยากรมากเกินไป

แอปสามารถใช้ Listener ที่ใช้ทรัพยากรมากเกินไปและลงทะเบียน Listener กับ CarWatchdogManager เพื่อรับการแจ้งเตือนเฉพาะแอปเมื่อเกินขีดจำกัด 80% หรือ 100% ของเกณฑ์การใช้งานดิสก์ I/O มากเกินไป แอปสามารถใช้การแจ้งเตือนเหล่านี้เพื่อดำเนินการต่อไปนี้

  • บันทึกสถิติการใช้งาน I/O ของดิสก์มากเกินไปสําหรับการวิเคราะห์แบบออฟไลน์ นักพัฒนาแอปสามารถใช้การบันทึกนี้เพื่อแก้ไขข้อบกพร่องของปัญหาการใช้ 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
    );
    }

ไคลเอ็นต์ในระบบ

  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. เริ่มพูลเธรด Binder และลงทะเบียนโปรแกรมรับฟังการใช้ทรัพยากรมากเกินไปกับเซิร์ฟเวอร์เฝ้าติดตาม เซิร์ฟเวอร์เฝ้าติดตามได้รับการจดทะเบียนภายใต้ชื่อบริการ 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 flag เพื่อดูสถิติการใช้งาน 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
     
}
}

ประสบการณ์ของผู้ใช้เมื่อใช้ทรัพยากรมากเกินไป

ส่วนต่อไปนี้จะอธิบายประสบการณ์ของผู้ใช้เมื่อเกิดการใช้ทรัพยากรมากเกินไป

ตั้งค่าประสิทธิภาพของแอปตามลำดับสำคัญ

หน้าการตั้งค่าของแอปมีการตั้งค่าสำหรับ 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) เมื่อแตะ รายชื่อแอปที่ถูกจํากัดเนื่องจากมีการใช้หน่วยความจําแฟลชมากเกินไปและส่งผลเสียต่อประสิทธิภาพของระบบจะปรากฏขึ้น ซึ่งเป็นไปตามข้อกําหนด CDD 3.5.1 [C-1-1]

แอปที่มีผลต่อประสิทธิภาพ

รูปที่ 1 แอปที่มีผลต่อประสิทธิภาพ

แอปที่สิ้นสุดลงเนื่องจากการใช้ทรัพยากรมากเกินไปจะแสดงอยู่ในรายการนี้ (ดูรูปที่ 2) คุณจัดลําดับความสําคัญของแอปที่แสดงได้ ดูข้อมูลเพิ่มเติมได้ที่ตั้งค่าให้เน้นที่ประสิทธิภาพของแอป

รายการแอปที่สิ้นสุดลงเนื่องจากใช้ทรัพยากรมากเกินไป

รูปที่ 2 รายการแอปที่สิ้นสุดลงเนื่องจากใช้ทรัพยากรมากเกินไป

การแจ้งเตือนผู้ใช้

เมื่อแอปหรือบริการใช้ I/O ของดิสก์ซ้ำๆ (เช่น เขียนข้อมูลลงในดิสก์เกินเกณฑ์ที่กำหนด) ภายในระยะเวลาหนึ่งและสามารถสิ้นสุดการใช้งานได้เนื่องจากมีการใช้ทรัพยากรมากเกินไป ผู้ใช้จะได้รับแจ้งหลังจากที่รถเข้าสู่สถานะ "อนุญาตการรบกวนในรถ"

การแจ้งเตือนผู้ใช้ครั้งแรก (ระหว่างขับรถ) จะแสดงเป็นข้อความแจ้งเตือนเพื่อแจ้งให้ทราบ และการแจ้งเตือนอื่นๆ จะแสดงในศูนย์การแจ้งเตือน

เช่น เมื่อแอปใช้ I/O ของดิสก์มากเกินไปซ้ำๆ ผู้ใช้จะได้รับการแจ้งเตือนต่อไปนี้

  • เมื่อผู้ใช้คลิกปุ่มให้ความสำคัญกับแอป ระบบจะเปิดหน้าการตั้งค่าของแอป ซึ่งผู้ใช้จะเปิดหรือปิดการตั้งค่าให้ความสำคัญกับประสิทธิภาพของแอปได้
  • เมื่อผู้ใช้คลิกปุ่มปิดใช้แอป แอปจะปิดใช้จนกว่าผู้ใช้จะเปิดแอปหรือเปิดใช้ในหน้าการตั้งค่าของแอป
  • สำหรับแอปที่ถอนการติดตั้งไม่ได้ ปุ่มปิดใช้แอปจะเปลี่ยนเป็นปุ่มถอนการติดตั้งแอป เมื่อผู้ใช้คลิกปุ่มถอนการติดตั้งแอป ระบบจะเปิดหน้าการตั้งค่าของแอปขึ้น ซึ่งผู้ใช้จะถอนการติดตั้งแอปได้จากหน้านี้

คำแนะนำสำหรับการใช้งาน Launcher

เมื่อแอปปิดใช้เนื่องจากใช้ทรัพยากรมากเกินไป แอปจะหายไปจากแอปตัวเปิดแอปเริ่มต้นเนื่องจาก CarService จะอัปเดตสถานะเปิดใช้ของแอปเป็น PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED OEM ต้องอัปเดตการใช้งาน Launcher ในตัวเพื่อแสดงแอปเหล่านี้ว่าผิดปกติเพื่อให้ผู้ใช้ใช้แอปดังกล่าวได้หากจำเป็น ดูคําแนะนําต่อไปนี้ตามรุ่นบิลด์

รุ่น Android SC V2