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

Watchdog จะตรวจสอบการใช้งานหน่วยความจำแฟลชโดยติดตามปริมาณ I/O ทั้งหมดของดิสก์ เขียนโดยแอปและบริการทั้งหมดที่ใช้สถิติ I/O ของดิสก์ต่อ UID เปิดเผยโดย Kernel ที่ตำแหน่ง `/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 ของดิสก์และ การดำเนินการ การกำหนดค่าเริ่มต้นของการใช้มากเกินไปจะกำหนดไว้ในระบบและผู้ให้บริการ และจัดส่งไปพร้อมกับบิลด์ ผู้ให้บริการ (ไม่บังคับ) จะรวมผู้ให้บริการ ในอิมเมจผู้ให้บริการ เมื่อไม่ได้กำหนดค่าผู้ให้บริการ จะมีการใช้การกำหนดค่าระบบสำหรับแอปของผู้ให้บริการ และ บริการได้อีกด้วย

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

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

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

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

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

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

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

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

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

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

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

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

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

ใช้รูปแบบ XML การกำหนดค่ามากเกินไป

วางการกำหนดค่าผู้ให้บริการเริ่มต้น (ตัวเลือกนี้ไม่บังคับ) ที่ตำแหน่งที่ตั้ง /vendor/etc/automotive/watchdog/resource_overuse_configuration.xml ในอิมเมจบิลด์ เมื่อไม่ได้ระบุการกำหนดค่านี้ ระบบกำหนด รวมถึงใช้กับแอปและบริการของผู้ให้บริการด้วย

ไฟล์ XML ควรมีแท็กเพียง 1 แท็กสำหรับช่องกำหนดค่าแต่ละช่อง การใช้งาน 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เพื่อรับ การกำหนดค่าที่มีอยู่ หากไม่ได้ใช้การกำหนดค่าที่มีอยู่ (รวมถึงการกำหนดค่าของระบบและของบุคคลที่สาม) ถูกเขียนทับ ซึ่งไม่แนะนำ
  • อัปเดตการกำหนดค่าที่มีอยู่ด้วยการเปลี่ยนแปลงแบบเดลต้าและตั้งค่าใหม่ การกำหนดค่าเอง อย่าอัปเดตระบบและคอมโพเนนต์ของบุคคลที่สาม การกำหนดค่าเอง
  • ใช้ API 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();
}

แอปที่ตรวจสอบการใช้ทรัพยากรมากเกินไป

ผู้ให้บริการและแอปของบุคคลที่สามจะรับฟังแหล่งข้อมูลเฉพาะแอปได้ ใช้การแจ้งเตือนมากเกินไปจาก 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 ไว้ในฟิลด์ ทรัพยากร Dependency 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. นำ 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 Thread Pool และลงทะเบียน 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()
}

ไคลเอ็นต์ดั้งเดิม

ใช้ CarWatchdogServer.getResourceOveruseStats เพื่อรับ สถิติการใช้ทรัพยากรมากเกินไป ส่ง enum ของ ResourceType.IO เพื่อดึงข้อมูลการใช้งานดิสก์ 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 ของดิสก์มากเกินไป (เช่น การเขียน ข้อมูลลงดิสก์เกินเกณฑ์ที่กำหนดไว้) ภายในระยะเวลาหนึ่ง และมีความปลอดภัย ถูกสิ้นสุดการใช้งานเนื่องจากการใช้ทรัพยากรมากเกินไป ผู้ใช้จะได้รับการแจ้งเตือนหลังจากที่รถเข้าไป สถานะ Allow-driver-distraction

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

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

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

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

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

รุ่น Android SC V2