監控快閃記憶體用量

監控磁碟 I/O 總量以監控快閃記憶體用量 一律根據 UID 磁碟 I/O 統計資料,由所有應用程式和服務產生的寫入作業 核心在 `/proc/uid_io/stats` 位置公開。應用程式 或服務超過磁碟 I/O 過度使用門檻,監控程式會 應用程式或服務磁碟 I/O 超額用量門檻和要採取的行動 系統會在磁碟 I/O 超額設定中預先定義。

過度使用閾值

  • 系統每天都會強制執行磁碟 I/O 超額用量門檻, 應用程式/服務所寫入的資料均來自於 目前的世界標準時間,並根據 過度使用設定
  • 在某一天駕駛車輛多次啟動時,監控計時器模組 儲存快閃記憶體的磁碟 I/O 使用統計資料,並在啟動後加以匯總 在這個日期 (世界標準時間) 當天的開頭。

過度使用動作

應用程式屢次超過定義的磁碟 I/O 過度使用時 會執行過度使用設定中定義的動作。

  • 所有供應商應用程式和服務都視為 整體系統穩定性,因此不會在磁碟 I/O 過度使用時終止。不過 如要定義安全分離的供應商應用程式清單 和服務
  • 所有第三方應用程式都會採用安全終止機制。

應用程式或服務在安全終止時,會停用該應用程式或服務。 元件狀態 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED

過度使用設定

超額使用設定內含磁碟 I/O 過度使用門檻 動作。系統和供應商會定義超額使用設定 映像檔,並與模型一起出貨供應商可以選擇納入供應商 定義供應商映像檔中的設定未啟用供應商設定時 後,系統設定就會用於供應商的應用程式 或服務

Watchdog 會透過 CarWatchdogManager 公開系統 API 供應商應用程式或服務更新供應商設定 。

過度使用設定定義

過度使用設定會依元件類型 (例如系統、廠商) 和第三方。原始設備製造商 (OEM) 只能更新供應商元件設定。

供應商設定

供應商設定可定義下列項目的磁碟 I/O 過度使用閾值和動作: 所有供應商的應用程式與服務,以及所有地圖和媒體應用程式。 設定包含下列設定欄位。

  • 供應商套件前置字串。安裝在 系統會將供應商分區視為供應商套件。 供應商可以將預先安裝的套件歸類為供應商套件, 將套件前置字元加入「供應商套件前置字串」設定。 這項設定不接受規則運算式。
  • 安全終止套件。供應商可以指定 只要在 safe-to-terminate 套件設定。
  • 應用程式類別對應。供應商可以對應任何套件 (包括第三方套件) 轉移至兩個支援的應用程式之一 類別 - 地圖和媒體應用程式。這項對應已完成提供地圖 媒體應用程式的磁碟 I/O 用量過高 相較於其他應用程式,應用程式通常在磁碟中下載及寫入的資料較多 。
  • 元件層級門檻:定義 供應商套件 (也就是不在特定套件專用套件涵蓋範圍內) 門檻應用程式類別專屬門檻: 這些門檻)。供應商必須在下列情況中,定義非零的元件層級門檻: 定義磁碟 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>

透過 CarWatchdogManager 系統 API 更新過度使用設定

上述 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 天內的統計資料過度使用。

監聽資源過度使用通知

應用程式可以實作資源過度使用的事件監聽器,並註冊 事件監聽器,在他們發現應用程式特定通知時,透過 CarWatchdogManager 接收應用程式專屬通知 磁碟 I/O 用量超過門檻的 80% 或 100%應用程式可以使用 這些通知到:

  • 記錄磁碟 I/O 過度使用統計資料以進行離線分析。應用程式 開發人員可以使用這項記錄功能來偵錯磁碟 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_user 巨集),並將供應商服務網域加進 carwatchdog用戶端網域 (carwatchdog_client_domain macro)。請查看下方 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. 繼承 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 伺服器 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);
    }
    

意見調查資源過度使用統計資料

應用程式可以針對應用程式專屬的 I/O 過度使用輪詢 CarWatchdogManager 最近 30 天的統計資料 ATS。

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 列舉,以擷取磁碟 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 天後,這項設定就會自動重設為預設值。每日上限可以是 利用 watchdogUserPackageSettingsResetDays 透過 RRO 疊加層應用程式修改, 最長 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 時,使用者會收到 下列通知:

  • 當使用者按一下「優先的應用程式」按鈕時, 啟動應用程式的設定頁面,使用者可在該頁面開啟或關閉 應用程式效能優先設定。
  • 當使用者按一下「停用應用程式」按鈕時,應用程式 會停用,直到使用者啟動應用程式,或是在應用程式的 設定頁面上。
,瞭解如何調查及移除這項存取權。
  • 可解除安裝應用程式的 [停用應用程式] 按鈕 替換成「解除安裝應用程式」按鈕。當使用者按一下 「解除安裝應用程式」按鈕,系統會啟動應用程式的「設定」頁面。 讓使用者能夠解除安裝應用程式。

建議導入啟動器

如果應用程式因資源過度使用而停用,應用程式就會從 預設啟動器應用程式,因為 CarService 會更新應用程式的啟用狀態 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED。 原始設備製造商 (OEM) 必須更新內建啟動器實作項目,才能以異常方式顯示這些應用程式。 方便使用者視需要使用以下根據建構版本查看相關建議。

Android SC V2 版本

,瞭解如何調查及移除這項存取權。