Android 8.1 Dozeモード分析(五)Dozeホワイトリスト及びDebug方式


1.Dozeモードでの免除適用とホワイトリスト
1.ホワイトリストとは?
一連のアプリケーションパッケージ名の集合.
2.何の役に立つの?
ホワイトリストにあるアプリケーションは、Dozeの影響を受けません.つまり、DozeはアプリケーションのJob、Alarm、ネットワークなど、アプリケーションを制限しません.
3.DeviceIdleControllerでのホワイトリストの読み取り
Dozeホワイトリストには2つのソースがあります.
  • 1.ユーザ設定
  • 2.プロファイルにプリセットします.
  • ユーザ設定は、最終的に/data/system/deviceidle.xmlファイルに書き込まれる.事前に値を設定できるプロファイルを見てみましょう.どのように読み取ったのか.onStart()メソッドでは、SystemConfigクラスを使用して2つのプロファイルを読み込みます.
        @Override
        public void onStart() {
            synchronized (this) {
    
                SystemConfig sysConfig = SystemConfig.getInstance();
                //               IDLE         ,    /etc/permissions/platform.xml 
                //        
                ArraySet<String> allowPowerExceptIdle = sysConfig.getAllowInPowerSaveExceptIdle();
                for (int i=0; i<allowPowerExceptIdle.size(); i++) {
                    String pkg = allowPowerExceptIdle.valueAt(i);
                    try {
                        //         ,   mPowerSaveWhitelistAppsExceptIdle 
                        ApplicationInfo ai = pm.getApplicationInfo(pkg,
                                PackageManager.MATCH_SYSTEM_ONLY);
                        int appid = UserHandle.getAppId(ai.uid);
                        mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
                        mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
                    } catch (PackageManager.NameNotFoundException e) {
                    }
                }
                //          IDLE          ,    /etc/permissions/platform.xml 
                //        
                ArraySet<String> allowPower = sysConfig.getAllowInPowerSave();
                for (int i=0; i<allowPower.size(); i++) {
                    String pkg = allowPower.valueAt(i);
                    try {
                        //         ,  mPowerSaveWhitelistAppsExceptIdle mPowerSaveWhitelistApps 
                        ApplicationInfo ai = pm.getApplicationInfo(pkg,
                                PackageManager.MATCH_SYSTEM_ONLY);
                        int appid = UserHandle.getAppId(ai.uid);
                        // These apps are on both the whitelist-except-idle as well
                        // as the full whitelist, so they apply in all cases.
                        mPowerSaveWhitelistAppsExceptIdle.put(ai.packageName, appid);
                        mPowerSaveWhitelistSystemAppIdsExceptIdle.put(appid, true);
                        mPowerSaveWhitelistApps.put(ai.packageName, appid);
                        mPowerSaveWhitelistSystemAppIds.put(appid, true);
                    } catch (PackageManager.NameNotFoundException e) {
                    }
                }
                //  /data/system/deviceidle.xml       mPowerSaveWhitelistUserApps 
                readConfigFileLocked();
                //          
                updateWhitelistAppIdsLocked();
            }
    
    したがって、システムアプリケーションについては、/etc/permissions/platform.xmlに予め設定することができ、サードパーティアプリケーションであれば、現在プリセット可能ではなく、手動で追加するしかない.またはxmlファイルをカスタマイズしてDeviceIdleControllerで読み込むこともできます.
    注意:/data/systemパーティションのデータは、出荷時の設定に戻すと消去されるため、/data/system/deviceidleにプリセットすることはできません.xmlで.
    4.ホワイトリストへの適用方法
  • 1.「設定」>「適用と通知」>「特別な適用権限」>「バッテリ最適化」で追加または削除します.
  • 2.システムアプリケーションの場合、/etc/permissions/platformにプリ値する.xmlで.
  • 5.ホワイトリストの適用を制限しない方法
    コードでは、DeviceIdleControllerではホワイトリストアプリケーションのリストしか収集されず、このリストを対応するモジュールに渡して具体的な制限作業を行います.
    //         AMS
    mLocalActivityManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
    //         PMS,  wakelock         
    mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
    //         Alarm,  Alarm         
    mLocalAlarmManager.setDeviceIdleUserWhitelist(mPowerSaveWhitelistUserAppIdArray);
    
    また、DICにはホワイトリストを取得するためのインタフェースも用意されており、他のモジュールはLocalServiceを介してDeviceIdleControllerからこのリストを取得します.
    int[] getPowerSaveWhitelistUserAppIds() {
        synchronized (this) {
            return mPowerSaveWhitelistUserAppIdArray;
        }
    }
    
    DeviceIdleJobControllerの場合:
    mDeviceIdleWhitelistAppIds =
            mLocalDeviceIdleController.getPowerSaveWhitelistUserAppIds();
    
    NOTE:setAndAllowWhileIdle()setExactAndAllowWhileIdle()で設定された目覚まし時計はDozeによって制限されません.
    2.Debug Doze
    DebugDozeはadb shell環境でdumpsysコマンドで実行できますが、まずバッテリの充電状態を未充電状態にする必要があります.
    adb shell dumpsys battery unplug   #           unplug
    
    その後、adb shell dumpsys deviceidleコマンドでDebugを実行し、adb shell dumpsys deviceidle helpですべてのパラメータを表示します.
    @ubuntu:~$ adb shell dumpsys deviceidle help
    Device idle controller (deviceidle) commands:
      help
        Print this help text.
      step [light|deep]
        Immediately step to next state, without waiting for alarm.
      force-idle [light|deep]
        Force directly into idle mode, regardless of other device state.
      force-inactive
        Force to be inactive, ready to freely step idle states.
      unforce
        Resume normal functioning after force-idle or force-inactive.
      get [light|deep|force|screen|charging|network]
        Retrieve the current given state.
      disable [light|deep|all]
        Completely disable device idle mode.
      enable [light|deep|all]
        Re-enable device idle mode after it had previously been disabled.
      enabled [light|deep|all]
        Print 1 if device idle mode is currently enabled, else 0.
      whitelist
        Print currently whitelisted apps.
      whitelist [package ...]
        Add (prefix with +) or remove (prefix with -) packages.
      except-idle-whitelist [package ...|reset]
        Prefix the package with '+' to add it to whitelist or '=' to check if it is already whitelisted
        [reset] will reset the whitelist to it's original state
        Note that unlike  cmd, changes made using this won't be persisted across boots
      tempwhitelist
        Print packages that are temporarily whitelisted.
      tempwhitelist [-u USER] [-d DURATION] [package ..]
        Temporarily place packages in whitelist for DURATION milliseconds.
        If no DURATION is specified, 10 seconds is used
    
    次のようになります.
    adb shell dumpsys deviceidle enable light    #   LightDoze  
    adb shell dumpsys deviceidle step light     #     ,     LightDoze    
    adb shell dumpsys deviceidle whitelist   #     Doze   
    adb shell dumpsys deviceidle whitelist +com.android.settings     # Settings     
    
    DICのdumpsysコマンドをマスターすることは、普段のデバッグに役立ちます.
    これでDozeモードの解析は一段落した.