11 展讯Sprd设置-电池-AppStateInfoCollector.reportAppStateEventInfo 代码走读

1. AppStateInfoCollector.reportAppStateEventInfo

package com.android.server.power;


public class AppStateInfoCollector {

    // return true: for new app state
    //     false: for others
    public boolean reportAppStateEventInfo(String packageName, int userId, int stateEvent) {
        ArrayMap<String, AppState> mAppStateInfoList = getAppStateInfoList(userId);

        //update mAppStateInfoList
        int index = mAppStateInfoList.indexOfKey(packageName);
        AppState appState = null;
        boolean ret = true;

        if (DEBUG) Slog.d(TAG, "- reportAppStateEventInfo() E -");

        if (index >= 0) {
            appState = mAppStateInfoList.valueAt(index);
            appState.updateAppState(stateEvent);
            ret = false;
        } else {
            appState = buildAppState(packageName, userId, stateEvent);
            mAppStateInfoList.put(packageName, appState);
        }

        return ret;
    }

2. PowerController.handleAppStateChanged

package com.android.server.power;

public class PowerController //extends IPowerController.Stub
	extends UsageStatsManagerInternal.AppStateEventChangeListener {

    private void handleAppStateChanged(String packageName, int userId, int state) {
        int oldState = state;
        ...
        if (mAppStateInfoCollector.reportAppStateEventInfo(packageName, userId, state)) {
            // Note: Bug 698133 appIdle cts fail -->BEG
            // Ugly: we have to check if doing cts/gts test
            // is cts/gts test, then
            checkCtsGtsTesting(packageName);
            // Note: Bug 698133 appIdle cts fail <--END
        }
  • 检查是否正在为CTS或gts测试
    // Note: Bug 698133 appIdle cts fail -->BEG
    // check if doing cts/gts test
    private void checkCtsGtsTesting(String pkgName) {
        // Ugly: we have to check if doing cts/gts test
        // is cts/gts test, then
        // 通过包名规则判断
        if (mIgnoreProcStateForAppIdle && Util.isCts(pkgName)) {
            if (DEBUG) Slog.d(TAG, "CTS/GTS app: " + pkgName + ", see as doing cts/gts test, clear mIgnoreProcStateForAppIdle!!");
            try {
                //LocalServices.getService(NetworkPolicyManagerInternal.class).setIgnoreProcStateForAppIdle(false);
                PowerControllerHelper.getInstance(mContext).setIgnoreProcStateForAppIdle(false);

                mIgnoreProcStateForAppIdle = false;
            } catch (Exception e) {
                Slog.d(TAG, "E:ignoreProcStateForAppIdle: "  + e);
            }
        }
    }

3. PowerController.onAppStateEventChanged MSG事件处理

    //Message define
    static final int MSG_APP_STATE_CHANGED = 0;

    switch (msg.what) {
        case MSG_APP_STATE_CHANGED:
            handleAppStateChanged((String)msg.obj, msg.arg1, msg.arg2);
            break;
            
    public void onAppStateEventChanged(String packageName, int userId, int state) {
        msgHandler.sendMessage(msgHandler.obtainMessage(MSG_APP_STATE_CHANGED, userId, state, packageName));
    }

4. grep -irn “onAppStateEventChanged” frameworks/

查看事件触发位置

  • root@69959bbb90c6:/home/suhuazhi/8.1/op54_int# grep -irn “onAppStateEventChanged” frameworks/
frameworks/base/services/usage/java/com/android/server/usage/UsageStatsService.java:1803:                listener.onAppStateEventChanged(packageName, userId, state);
frameworks/base/core/java/android/app/usage/UsageStatsManagerInternal.java:148:        public abstract void onAppStateEventChanged(String packageName, int userId, int stateEvent);

  • frameworks/base/core/java/android/app/usage/UsageStatsManagerInternal.java
package android.app.usage;

/**
 * UsageStatsManager local system service interface.
 *
 * {@hide} Only for use within the system server.
 */
public abstract class UsageStatsManagerInternal {

    // 定义一个监听器
    public static abstract class AppStateEventChangeListener {
        public abstract void onAppStateEventChanged(String packageName, int userId, int stateEvent);
    }

    // 
    
  • frameworks/base/services/usage/java/com/android/server/usage/UsageStatsService.java
    // inone add start by suhuazhi for powersave
    public void informAppStateEventChangeListeners(String packageName, int userId, int state) {
        for (UsageStatsManagerInternal.AppStateEventChangeListener listener : mAppStateEventListeners) {
            listener.onAppStateEventChanged(packageName, userId, state);
        }
    }
    // inone add end by suhuazhi for powersave

5. UsageStatsService.PowerControllerHelper.informAppStateEventChangeListeners

package com.android.server.usage;

/**
 * A service that collects, aggregates, and persists application usage data.
 * This data can be queried by apps that have been granted permission by AppOps.
 */
public class UsageStatsService extends SystemService implements
        UserUsageStatsService.StatsUpdatedListener {

    private final class PowerControllerHelper {

        static final int MSG_INFORM_APP_STATE = MSG_ONE_TIME_CHECK_IDLE_STATES + 1;

        public void informAppStateEventChangeListeners(String packageName, int userId, int state) {
            for (UsageStatsManagerInternal.AppStateEventChangeListener listener : mAppStateEventListeners) {
                listener.onAppStateEventChanged(packageName, userId, state);
            }
        }
    
        public boolean handleMessage(Message msg) {
            boolean ret = false;
    
            switch (msg.what) {
                case MSG_INFORM_APP_STATE:
                    informAppStateEventChangeListeners((String)msg.obj, msg.arg1, msg.arg2);
                    ret = true;
                    break;
            }
    
            return ret;
        }
    }

6. UsageStatsService.PowerControllerHelper.reportEvent

package com.android.server.usage;

/**
 * A service that collects, aggregates, and persists application usage data.
 * This data can be queried by apps that have been granted permission by AppOps.
 */
public class UsageStatsService extends SystemService implements
        UserUsageStatsService.StatsUpdatedListener {
        
        public boolean reportEvent(UsageEvents.Event event, int userId, boolean previouslyIdle, long elapsedRealtime) {

            final boolean forceIdle = mAppIdleHistory.isForceIdleFlagSet(
                    event.mPackage, userId, elapsedRealtime);
            if (!forceIdle
                || event.mEventType == Event.MOVE_TO_FOREGROUND
                || event.mEventType == Event.USER_INTERACTION) {

                mAppIdleHistory.reportUsage(event.mPackage, userId, elapsedRealtime);
                if (previouslyIdle) {

                    mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS, userId,
                            /* idle = */ 0, event.mPackage));
                    notifyBatteryStats(event.mPackage, userId, false);
                }
            }

            mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_APP_STATE, userId, event.mEventType, event.mPackage));

            return true;
        }

7. UsageStatsService.reportEvent

    /**
     * Called by the Binder stub.
     */
    void reportEvent(UsageEvents.Event event, int userId) {
        ...
        if (mPowerControllerHelper != null
            && mPowerControllerHelper.reportEvent(event, userId, previouslyIdle, elapsedRealtime)) {
            return;
        }
        ....

8. reportEvent触发事件源

reportEvent触发事件源.jpg

8.1 进程前台和后台状态切换

    if (resumed) {
        if (mUsageStatsService != null) {
            mUsageStatsService.reportEvent(component.realActivity, component.userId,
                    UsageEvents.Event.MOVE_TO_FOREGROUND);
        }
    ....
    } else {
        if (mUsageStatsService != null) {
            mUsageStatsService.reportEvent(component.realActivity, component.userId,
                    UsageEvents.Event.MOVE_TO_BACKGROUND);
        }
    ......
    }

8.1 SYSTEM_INTERACTION 状态变更

AcitivityManagerService#applyOomAdjLocked() -> ActivityManagerService#maybeUpdateUsageStatsLocked() -> mUsageStatsService.reportEvent(packages[i], app.userId, UsageEvents.Event.SYSTEM_INTERACTION);

    if (eventType != UsageEvents.Event.SYSTEM_INTERACTION) {
        usageStats.mLastTimeUsed = timeStamp;
    }

8.3 /data/system/usagestats 数据存储

  1. 手机关机,具体见:UsageStatsService.java#shutdown
  2. 系统时间跳变(如人为修改系统时间或时间随网络校准)
  3. 一天结束时,因为daily下面xml文件存储一天的数据,此时需下次新建文件
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>

       <usagestats version="1" endTime="93054">

             <packages>

                   <package lastTimeActive="92995" package="com.android.settings" timeActive="87841" lastEvent="2" />

                   <package lastTimeActive="93054" package="com.miui.home" timeActive="5076" lastEvent="1" />

             </packages>

       <configurations>

             <config lastTimeActive="0" timeActive="0" count="1" active="true" fs="1065353216" locales="zh-CN" touch="3" key="1" keyHid="1" hardKeyHid="2" nav="1" navHid="2" ori="1" scrLay="268435810" ui="17" width="360" height="620" sw="360" density="480" />

       </configurations>

       <event-log>

             <event time="0" package="com.android.settings" class="com.android.settings.UsageStatsActivity" type="2" />

             <event time="61" package="com.miui.home" class="com.miui.home.launcher.Launcher" type="1" />

             <event time="5137" package="com.miui.home" class="com.miui.home.launcher.Launcher" type="2" />

             <event time="5154" package="com.android.settings" class="com.android.settings.MiuiSettings" type="1" />

             <event time="92995" package="com.android.settings" class="com.android.settings.MiuiSettings" type="2" />

             <event time="93054" package="com.miui.home" class="com.miui.home.launcher.Launcher" type="1" />

    </event-log>

</usagestats>

XML中package的lastEvent字段,event-log的type字段,都是指上面介绍过的事件类型。但是注意,事件类型是有7种,但真正记录在XML中,除了4种(MOVE_TO_FOREGROUND,MOVE_TO_BACKGROUND,END_OF_DAY,CONTINUE_PREVIOUS_DAY)记录其int值,其他的事件(CONFIGURATION_CHANGE,SYSTEM_INTERACTION,USER_INTERACTION)都记录为0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

法迪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值