Giám sát mức sử dụng bộ nhớ flash

Bộ đếm giờ phòng vệ giám sát mức sử dụng bộ nhớ flash bằng cách theo dõi tổng dung lượng ổ đĩa I/O hoạt động ghi do tất cả các ứng dụng và dịch vụ thực hiện bằng cách sử dụng số liệu thống kê I/O ổ đĩa trên mỗi UID được hiển thị bởi Kernel tại vị trí "/proc/uid_io/stats". Khi một ứng dụng hoặc dịch vụ vượt quá ngưỡng lạm dụng I/O của ổ đĩa, Bộ theo dõi sẽ thực hiện hành động đối với ứng dụng hoặc dịch vụ của bạn. Ngưỡng tình trạng sử dụng quá mức của ổ đĩa I/O và biện pháp xử lý tình trạng sử dụng quá mức được xác định trước trong cấu hình tình trạng sử dụng quá mức của ổ đĩa I/O.

Ngưỡng lạm dụng

  • Các ngưỡng tình trạng sử dụng quá mức của ổ đĩa I/O được thực thi hằng ngày, tức là tất cả số lượt ghi do một ứng dụng/dịch vụ thực hiện được tổng hợp kể từ khi bắt đầu ngày hiện tại theo lịch UTC và được kiểm tra so với các ngưỡng đã xác định trong cấu hình lạm dụng.
  • Khi xe khởi động nhiều lần trong một ngày cụ thể, mô-đun Bộ theo dõi lưu trữ số liệu thống kê sử dụng I/O của ổ đĩa vào bộ nhớ flash và tổng hợp chúng kể từ khi đầu ngày hiện tại theo lịch UTC.

Thao tác lạm dụng

Khi một ứng dụng liên tục vượt quá tình trạng sử dụng quá mức ổ đĩa I/O đã xác định Các ngưỡng này sẽ thực hiện các hành động được xác định trong cấu hình việc sử dụng quá mức.

  • Tất cả các ứng dụng và dịch vụ của nhà cung cấp đều được coi là quan trọng đối với độ ổn định tổng thể của hệ thống, nhờ đó không bị chấm dứt khi sử dụng ổ đĩa I/O quá mức. Tuy nhiên, cấu hình sử dụng quá mức có thể xác định một danh sách các ứng dụng an toàn của nhà cung cấp để chấm dứt và các dịch vụ khác.
  • Tất cả các ứng dụng của bên thứ ba đều an toàn để chấm dứt.

Khi một ứng dụng hoặc dịch vụ bị chấm dứt an toàn, Watchdog sẽ tắt ứng dụng hoặc dịch vụ đó với ứng dụng trạng thái thành phần PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED .

Cấu hình lạm dụng

Cấu hình việc sử dụng quá mức có chứa các ngưỡng sử dụng quá mức của ổ đĩa I/O và hành động. Cấu hình mặc định cho việc sử dụng quá mức được xác định trong hệ thống và nhà cung cấp hình ảnh và được gửi cùng với bản dựng. Nhà cung cấp có thể tuỳ ý thêm nhà cung cấp trong hình ảnh nhà cung cấp. Khi không có cấu hình của nhà cung cấp được cung cấp, cấu hình hệ thống sẽ được dùng cho các ứng dụng của nhà cung cấp và dịch vụ trực tuyến.

Watchdog hiển thị các API hệ thống thông qua CarWatchdogManager, cho phép các ứng dụng hoặc dịch vụ của nhà cung cấp cập nhật cấu hình của nhà cung cấp bất cứ lúc nào.

Định nghĩa cấu hình lạm dụng

Cấu hình sử dụng quá mức được chia theo loại thành phần, ví dụ: hệ thống, nhà cung cấp, và bên thứ ba. OEM chỉ được cập nhật cấu hình thành phần của nhà cung cấp.

Cấu hình nhà cung cấp

Cấu hình nhà cung cấp xác định các ngưỡng và cách xử lý việc sử dụng quá mức của ổ đĩa I/O đối với tất cả các ứng dụng và dịch vụ của nhà cung cấp, cũng như tất cả các ứng dụng bản đồ và đa phương tiện. Chiến lược phát hành đĩa đơn chứa các trường cấu hình bên dưới.

  • Tiền tố gói nhà cung cấp. Tất cả các gói đã cài đặt trong phân vùng nhà cung cấp được coi là gói nhà cung cấp. Ngoài những của nhà cung cấp, nhà cung cấp có thể phân loại các gói được cài đặt trước là gói của nhà cung cấp theo thêm các tiền tố gói vào cấu hình tiền tố gói nhà cung cấp. Cấu hình này không chấp nhận biểu thức chính quy.
  • Các gói an toàn để chấm dứt. Nhà cung cấp có thể chỉ định nhà cung cấp nào có thể chấm dứt gói một cách an toàn bằng cách thêm tên gói đầy đủ vào an toàn để kết thúc các gói.
  • Liên kết danh mục ứng dụng. Nhà cung cấp có thể liên kết bất kỳ gói nào (bao gồm các gói của bên thứ ba) vào một trong hai ứng dụng được hỗ trợ danh mục – Ứng dụng bản đồ và ứng dụng đa phương tiện. Việc lập bản đồ này được thực hiện để cung cấp bản đồ và ứng dụng đa phương tiện có ngưỡng sử dụng quá mức ổ đĩa I/O cao hơn vì các ứng dụng có xu hướng tải xuống và ghi nhiều dữ liệu vào đĩa hơn so với các ứng dụng khác loại.
  • Ngưỡng cấp thành phần. Xác định các ngưỡng chung cho tất cả gói của nhà cung cấp (tức là các gói không thuộc phạm vi của chế độ Theo gói cụ thể hoặc Ngưỡng cụ thể theo danh mục ứng dụng sẽ được tính các ngưỡng này). Nhà cung cấp phải xác định ngưỡng cấp thành phần khác 0 khi xác định cấu hình lạm dụng I/O của ổ đĩa.
  • Ngưỡng cụ thể theo gói. Nhà cung cấp có thể xác định các chỉ số đặc biệt các ngưỡng cho các gói nhà cung cấp cụ thể. Ánh xạ phải chứa tên gói hoàn chỉnh. Các ngưỡng đã xác định trong cấu hình này sẽ được ưu tiên vượt quá ngưỡng được xác định trong các cấu hình khác cho một gói nhất định.
  • Ngưỡng cụ thể đối với danh mục ứng dụng. Nhà cung cấp có thể chỉ định các ngưỡng đặc biệt cho các danh mục ứng dụng cụ thể. Ứng dụng danh mục phải là một trong các danh mục được hỗ trợ - Bản đồ và Phương tiện của chúng tôi. Các ngưỡng được xác định trong cấu hình này được liên kết với bằng cách sử dụng Ánh xạ danh mục ứng dụng.
  • Ngưỡng trên toàn hệ thống. Nhà cung cấp không được chỉ định cấu hình này.

Tiền tố gói của nhà cung cấp, Gói an toàn để kết thúc, Ngưỡng cấp thành phầnTheo gói cụ thể các ngưỡng mới được cập nhật nhờ cấu hình của nhà cung cấp ứng dụng và dịch vụ của nhà cung cấp. Cụ thể về danh mục ứng dụng Các ngưỡng chỉ có thể được cập nhật bằng cấu hình nhà cung cấp cho tất cả bản đồ và ứng dụng đa phương tiện.

Các ngưỡng sử dụng quá mức chứa số byte được phép ghi trong thời gian:

  • Chế độ trên nền trước của ứng dụng hoặc dịch vụ so với chế độ nền
  • Chế độ gara của hệ thống

Cách phân loại này cho phép các ứng dụng và dịch vụ trên nền trước mà người dùng nhìn thấy ghi nhiều dữ liệu hơn so với ứng dụng và dịch vụ nền. Ở Chế độ nhà để xe, các ứng dụng và dịch vụ có xu hướng tải bản cập nhật xuống, vì vậy, mỗi ứng dụng và dịch vụ đều cần ngưỡng cao hơn so với các ứng dụng và dịch vụ chạy ở các chế độ khác.

Cấu hình của hệ thống và bên thứ ba

OEM không được cập nhật hệ thống và cấu hình của bên thứ ba.

  • Cấu hình hệ thống xác định các ngưỡng I/O sử dụng quá mức và các hành động đối với các ứng dụng và dịch vụ hệ thống.
    • Cấu hình này cũng có thể cập nhật Danh mục ứng dụng ánh xạ. Do đó, trường cấu hình này được chia sẻ giữa hệ thống và nhà cung cấp .
  • Cấu hình của bên thứ ba xác định các ngưỡng cho tất cả các bên thứ ba của chúng tôi. Tất cả các ứng dụng chưa được cài đặt trước trong hệ thống đều ứng dụng bên thứ ba.
    • Tất cả các ứng dụng bên thứ ba đều nhận được cùng một ngưỡng (ví dụ: không ứng dụng bên thứ ba nhận được các ngưỡng đặc biệt), ngoại trừ bản đồ và nội dung nghe nhìn những ứng dụng có các ngưỡng được xác định theo cấu hình của nhà cung cấp.
    • Các ngưỡng sử dụng quá mức ổ đĩa I/O dưới đây là ngưỡng mặc định cho ứng dụng bên thứ ba. Các ngưỡng này được vận chuyển cùng với hình ảnh hệ thống.
      • 3 GiB ghi ở chế độ nền trước của ứng dụng.
      • 2 Ghi GiB ở chế độ nền của ứng dụng.
      • 4 Ghi GiB ở chế độ gara của hệ thống.
    • Đây là các ngưỡng cơ bản. Các ngưỡng này được cập nhật khi có thêm thông tin về ổ đĩa I/O mức sử dụng.

Sử dụng quá mức định dạng XML cấu hình

Bạn có thể đặt cấu hình mặc định của nhà cung cấp (đây là không bắt buộc) tại vị trí /vendor/etc/automotive/watchdog/resource_overuse_configuration.xml trong hình ảnh bản dựng. Khi cấu hình này không được chỉ định, hệ thống sẽ xác định cấu hình này cũng được áp dụng cho các ứng dụng và dịch vụ của nhà cung cấp.

Tệp XML chỉ được chứa một thẻ cho mỗi trường cấu hình. Sử dụng I/O quá mức phải được xác định trong tệp XML. Tất cả các giá trị ngưỡng phải là được chỉ định trong đơn vị MiB.

Dưới đây là một cấu hình XML mẫu:

<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>

Cập nhật cấu hình sử dụng quá mức thông qua API hệ thống CarWatchdogManager

Bạn chỉ có thể cung cấp cấu hình XML ở trên trong hình ảnh bản dựng. Nếu một OEM chọn cập nhật cấu hình trên thiết bị sau khi bản dựng được phát hành, họ có thể dùng các API sau để thay đổi cấu hình trên thiết bị.

  • Cấp quyền Car.PERMISSION_CONTROL_CAR_WATCHDOG_CONFIG cho người gọi.
  • Phải dùng các cấu hình hiện có để cập nhật và thiết lập các cấu hình mới. Sử dụng API CarWatchdogManager.getResourceOveruseConfigurations để nhận các cấu hình hiện có. Nếu không sử dụng các cấu hình hiện có, tất cả cấu hình (bao gồm cả cấu hình của hệ thống và bên thứ ba) là bị ghi đè. Bạn không nên làm điều này.
  • Cập nhật các cấu hình hiện có với các thay đổi delta và đặt giá trị mới . Không cập nhật hệ thống và thành phần bên thứ ba .
  • Sử dụng API CarWatchdogManager.setResourceOveruseConfigurations để thiết lập cấu hình mới.
  • Để nhận và thiết lập cấu hình tình trạng sử dụng quá mức của ổ đĩa I/O, hãy sử dụng cờ CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO.

Dưới đây là một ví dụ triển khai nhằm cập nhật cấu hình sử dụng tài nguyên quá mức:

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();
}

Ứng dụng giám sát việc sử dụng tài nguyên quá mức

Nhà cung cấp và ứng dụng bên thứ ba có thể theo dõi tài nguyên dành riêng cho ứng dụng thông báo lạm dụng từ Bộ đếm giờ phòng hoặc cuộc thăm dò ý kiến CarWatchdogManager cho ứng dụng số liệu thống kê cụ thể về việc lạm dụng tài nguyên trong tối đa 30 ngày qua.

Nghe thông báo về việc sử dụng tài nguyên quá mức

Các ứng dụng có thể triển khai trình nghe tình trạng sử dụng tài nguyên quá mức và đăng ký trình nghe bằng CarWatchdogManager để nhận các thông báo dành riêng cho ứng dụng khi chúng vượt quá 80% hoặc 100% ngưỡng sử dụng quá mức của ổ đĩa I/O. Các ứng dụng có thể sử dụng những thông báo này để:

  • Ghi lại số liệu thống kê của ổ đĩa I/O bị sử dụng quá mức để phân tích ngoại tuyến. Chiến dịch Quảng cáo ứng dụng các nhà phát triển có thể sử dụng nhật ký này để gỡ lỗi vấn đề lạm dụng ổ đĩa I/O.
  • Giảm số lượt ghi I/O trên ổ đĩa cho đến khi bộ đếm tình trạng sử dụng quá mức được đặt lại.

Ứng dụng Java

  1. Triển khai trình nghe bằng cách kế thừa 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. Đăng ký thực thể trình nghe bằng cách gọi 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. Huỷ đăng ký thực thể trình nghe khi ứng dụng nghe xong:
    private void removeResourceOveruseListener() {
        CarWatchdogManager manager =
                (CarWatchdogManager) car.getCarManager(Car.CAR_WATCHDOG_SERVICE);
        mCarWatchdogManager.removeResourceOveruseListener(
              mListenerImpl);
    }
    

Ứng dụng gốc

  1. Đưa carwatchdog_aidl_interface-ndk_platform vào Phần phụ thuộc shared_libs của quy tắc bản dựng.

    Android.bp

    cc_binary {
        name: "sample_native_client",
        srcs: [
            "src/*.cpp"
        ],
        shared_libs: [
            "carwatchdog_aidl_interface-ndk_platform",
            "libbinder_ndk",
        ],
        vendor: true,
    }
    
  2. Thêm chính sách SELinux để cho phép miền dịch vụ của nhà cung cấp sử dụng trình liên kết (macro binder_user) và thêm miền dịch vụ của nhà cung cấp vào Miền ứng dụng carwatchdog trên (carwatchdog_client_domain macro). Xem mã bên dưới cho sample_client.tefile_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. Triển khai trình nghe tình trạng sử dụng tài nguyên quá mức bằng cách kế thừa BnResourceOveruseListener. Ghi đè BnResourceOveruseListener::onOveruse để xử lý việc sử dụng tài nguyên quá mức thông báo.

    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. Bắt đầu một nhóm luồng liên kết và đăng ký trình nghe tình trạng sử dụng tài nguyên bị sử dụng nhiều với máy chủ bộ đếm giờ phòng vệ. Máy chủ theo dõi được đăng ký theo tên dịch vụ 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);
    }
    

Số liệu thống kê về việc sử dụng tài nguyên quá mức trong cuộc thăm dò ý kiến

Các ứng dụng có thể thăm dò ý kiến của CarWatchdogManager để biết việc sử dụng quá mức I/O dành riêng cho ứng dụng ATS thống kê cho 30 ngày gần đây nhất.

Ứng dụng Java

Sử dụng CarWatchdogManager.getResourceOveruseStats để lấy số liệu thống kê về việc lạm dụng tài nguyên. Truyền CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO gắn cờ để lấy số liệu thống kê về tình trạng sử dụng quá mức của ổ đĩa 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()
}

Ứng dụng gốc

Sử dụng CarWatchdogServer.getResourceOveruseStats để lấy số liệu thống kê về việc lạm dụng tài nguyên. Truyền enum ResourceType.IO để tìm nạp tình trạng sử dụng quá mức của ổ đĩa I/O thống kê.

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
      }
}

Trải nghiệm người dùng về việc lạm dụng tài nguyên

Các phần sau đây mô tả trải nghiệm người dùng khi việc sử dụng tài nguyên quá mức xảy ra.

Ưu tiên chế độ cài đặt hiệu suất của ứng dụng

Trang Cài đặt của ứng dụng chứa các chế độ cài đặt choPrioritize app performance (xem hình bên dưới), cho phép người dùng ưu tiên hiệu suất của ứng dụng hơn hệ thống và hiệu suất phần cứng lâu dài. Chế độ cài đặt này chỉ dành cho những ứng dụng an toàn bị chấm dứt khi sử dụng tài nguyên quá mức. Nếu không, chế độ cài đặt này sẽ bị tắt. Khi chế độ này là tắt (chế độ cài đặt mặc định) cho một ứng dụng, thì ứng dụng đó có thể bị chấm dứt khi sử dụng tài nguyên quá mức. Nếu không, ứng dụng sẽ không bị chấm dứt khi sử dụng quá mức tài nguyên.

Khi người dùng bật chế độ cài đặt này, hộp thoại xác nhận sau đây sẽ mô tả tác động của việc bật/tắt chế độ cài đặt:

Sau 90 ngày, chế độ cài đặt này sẽ tự động được đặt lại về mặc định. Giới hạn ngày có thể là được sửa đổi bằng ứng dụng lớp phủ RRO sử dụng watchdogUserPackageSettingsResetDays, tối đa 180 ngày. Để tìm hiểu thêm, hãy xem Thay đổi giá trị của tài nguyên của ứng dụng trong thời gian chạy. Chiến lược phát hành đĩa đơn có thể bao gồm thẻ lớp phủ mẫu sau trong AndroidManifest.xml:

<overlay android:priority="<insert-value>"
      android:targetPackage="com.android.car.updatable"
      android:targetName="CarServiceCustomization"
      android:resourcesMap="@xml/overlays" />

Trong res/values/config.xml:

<resources>
  <integer name="watchdogUserPackageSettingsResetDays">value</integer>
</resources>

Trong res/xml/overlays.xml:

<overlay>
  <item target="integer/watchdogUserPackageSettingsResetDays" value="@integer/watchdogUserPackageSettingsResetDays" />
</overlay>

Chế độ cài đặt các ứng dụng ảnh hưởng đến hiệu suất

Ứng dụng Cài đặt có phần Ứng dụng ảnh hưởng đến hiệu suất (xem Hình 1). Khi được nhấn, danh sách các ứng dụng đã bị hạn chế do bộ nhớ flash việc sử dụng quá mức và tác động tiêu cực đến hiệu suất của hệ thống đều được hiển thị. Điều này tuân theo Yêu cầu CDD 3.5.1 [C-1-1].

Ứng dụng ảnh hưởng đến hiệu suất

Hình 1. Những ứng dụng ảnh hưởng đến hiệu suất.

Các ứng dụng bị chấm dứt do sử dụng tài nguyên quá mức được liệt kê tại đây (xem Hình 2). Ứng dụng trong danh sách có thể được ưu tiên. Để tìm hiểu thêm, hãy xem Ưu tiên chế độ cài đặt hiệu suất của ứng dụng.

Danh sách ứng dụng bị chấm dứt do sử dụng tài nguyên quá mức

Hình 2. Danh sách ứng dụng đã chấm dứt do sử dụng tài nguyên quá mức.

Thông báo dành cho người dùng

Khi một ứng dụng hoặc dịch vụ liên tục sử dụng quá mức ổ đĩa I/O (ví dụ: ghi vào ổ đĩa ngoài ngưỡng đã xác định) trong một khoảng thời gian nhất định và được coi là an toàn sẽ bị chấm dứt khi sử dụng tài nguyên quá mức, người dùng sẽ nhận được thông báo sau khi xe đi vào trạng thái cho phép-người lái xe mất tập trung.

Thông báo đầu tiên dành cho người dùng (trong khi lái xe) được đăng dưới dạng thông báo quan trọng và các thông báo khác được đăng trên thông báo đó giữa chiến dịch.

Ví dụ: khi một ứng dụng liên tục sử dụng ổ đĩa I/O quá mức, người dùng sẽ nhận được thông báo sau đây:

  • Khi người dùng nhấp vào nút Ưu tiên ứng dụng, Trang cài đặt của ứng dụng đang chạy, tại đây người dùng có thể bật hoặc tắt Chế độ cài đặt Ưu tiên hiệu suất của ứng dụng.
  • Khi người dùng nhấp vào nút Tắt ứng dụng, ứng dụng bị tắt cho đến khi người dùng khởi chạy ứng dụng hoặc bật ứng dụng trên trang cài đặt.
  • Đối với các ứng dụng có thể gỡ cài đặt, nút Disable app (Tắt ứng dụng) là được thay thế bằng nút Gỡ cài đặt ứng dụng. Khi người dùng nhấp vào Nút Gỡ cài đặt ứng dụng, trang Cài đặt của ứng dụng được khởi chạy, mà từ đó người dùng có thể gỡ cài đặt ứng dụng.

Đề xuất cho việc triển khai trình chạy

Khi ứng dụng bị vô hiệu hoá do sử dụng tài nguyên quá mức, các ứng dụng đó sẽ biến mất khỏi ứng dụng trình chạy mặc định vì CarService cập nhật ứng dụng trạng thái đã bật dưới dạng PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED. OEM phải cập nhật phương thức triển khai trình chạy tích hợp để cho thấy những ứng dụng này dưới dạng bất thường, để người dùng có thể sử dụng khi cần. Xem các đề xuất sau đây dựa trên bản phát hành.

Bản phát hành Android SC V2