9 展讯Sprd设置-电池-关联唤醒拦截位置

1. 关联唤醒机制

关联唤醒中的原理在于在应用启动的各种通道中进行拦截

  1. 在ActivityStarter 进行 start-activity 监听,judgeStartAllowLocked 判断是否拦截
  2. 在ActivityManagerService 进行 contentprovider 监听,judgeStartAllowLocked 判断是否拦截
  3. 在BroadcastQueue 进行 send-broadcast,judgeStartAllowLocked 判断是否拦截
  4. 在ActiveServices 进行 start-service 和 bind-service监听,judgeStartAllowLocked 判断是否拦截

2. 源码搜索

  • grep -irn “judgeStartAllowLocked” frameworks/base/services/

搜索结果覆盖进程的四大组件启动位置,即覆盖完应用的所有启动入口

frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java:345:        if(!mService.judgeStartAllowLocked(intent, targetPkg, targetUid, callingUid, callingPackage, "start-activity")){

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:11927:                    if(!judgeStartAllowLocked(null, targetPkg, targetUid, callerUid, callingPackage,"contentprovider")) {

frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java:1204:                skip = skip || !mService.judgeStartAllowLocked(r.intent, info.activityInfo.applicationInfo.packageName,

frameworks/base/services/core/java/com/android/server/am/ActiveServices.java:394:        if(!mAm.judgeStartAllowLocked(service, r.packageName, targetUid, callingUid, callingPackage,"start-service")) {

frameworks/base/services/core/java/com/android/server/am/ActiveServices.java:1311:        if(!mAm.judgeStartAllowLocked(service, targetPkg, targetUid, callingUid, callingPackage,"bind-service")) {

3. 关联唤醒拦截-start-activity类型拦截

  • 源码 frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
package com.android.server.am;

/**
 * Controller for interpreting how and then launching activities.
 *
 * This class collects all the logic for determining how an intent and flags should be turned into
 * an activity and associated task and stack.
 */
class ActivityStarter {

    /**
     * Result for IActivityManager.startActivity: an error where the
     * given Intent could not be resolved to an activity.
     * @hide
     */
    public static final int START_INTENT_NOT_RESOLVED = FIRST_START_FATAL_ERROR_CODE + 9;
    
    private final ActivityManagerService mService;
    
    ActivityStarter(ActivityManagerService service, ActivityStackSupervisor supervisor) {
        // 这个 service 只能是继承 ActivityManagerService 的 ActivityManagerServiceEx
        mService = service;
        ...
    }

    /** DO NOT call this method directly. Use {@link #startActivityLocked} instead. */
    private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, TaskRecord inTask) {

        ......
        // 拦截 activity 类型启动
        // NOTE: Bug #627645 low power Feature BEG-->
        String targetPkg = null;
        int targetUid = aInfo != null ? aInfo.applicationInfo.uid : 0;
        if (intent.getComponent() != null) targetPkg = intent.getComponent().getPackageName();
        // 这里有个疑问:
        // 目前继承的关系是:ActivityManagerServiceEx extend ActivityManagerService extend ActivityManagerServiceExAbs
        // 当前是 ActivityManagerService.judgeStartAllowLocked 引用的方法是 ActivityManagerServiceExAbs.judgeStartAllowLocked
        // 但是实际方法是 ActivityManagerServiceEx.judgeStartAllowLocked,
        // 即父类ActivityManagerService无法引用到子类 ActivityManagerServiceEx 方法,即该函数是否无法执行到?
        
        // 回答上述,其实AMS被启动入口中Lifecycle.class
        // 将ActivityManagerService 实例化为 ActivityManagerServiceEx,即这里的mService其实是ActivityManagerServiceEx
        // 故不冲突,该框架很不错
        if(!mService.judgeStartAllowLocked(intent, targetPkg, targetUid, callingUid, callingPackage, "start-activity")){
            return ActivityManager.START_INTENT_NOT_RESOLVED;
        }
        // <-- NOTE: Bug #627645 low power Feature END
        // 其他代码位置,参考点
        ActivityRecord sourceRecord = null;
        ActivityRecord resultRecord = null;
        if (resultTo != null) {
            sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
            if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
                    "Will send result to " + resultTo + " " + sourceRecord);
            if (sourceRecord != null) {
                if (requestCode >= 0 && !sourceRecord.finishing) {
                    resultRecord = sourceRecord;
                }
            }
        }
        ....

3.1 ActivityManagerService.judgeStartAllowLocked

==================================================================================
package com.android.server.am;

public class ActivityManagerService extends ActivityManagerServiceExAbs
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    
    public static final class Lifecycle extends SystemService {
        private final ActivityManagerService mService;

        public Lifecycle(Context context) {
            super(context);
            mService = new ActivityManagerServiceEx(context);
        }

        @Override
        public void onStart() {
            mService.start();
        }

        @Override
        public void onCleanupUser(int userId) {
            mService.mBatteryStatsService.onCleanupUser(userId);
        }

        public ActivityManagerService getService() {
            return mService;
        }
    }    
==================================================================================
// 基类定义了 judgeStartAllowLocked
vendor/sprd/platform/frameworks/base/services/core/java/com/android/server/am/ActivityManagerServiceExAbs.java

package com.android.server.am;

public abstract class ActivityManagerServiceExAbs extends IActivityManager.Stub {

    // 在子类ActivityManagerServiceEx中实现
    protected boolean judgeStartAllowLocked(Intent intent, String targetPkg, int targetUid,
        int callingUid, String callingPackage, String reason){
        return true;
    }
    
==================================================================================
package com.android.server.am;

// 子类 ActivityManagerServiceEx 继承ActivityManagerService继承ActivityManagerServiceExAbs
// 子子类 ActivityManagerServiceEx 实现了 judgeStartAllowLocked 的方法
public class ActivityManagerServiceEx extends ActivityManagerService {

    // NOTE: Bug #627645 low power Feature BEG-->
    protected boolean judgeStartAllowLocked(Intent intent, String targetPkg, int targetUid,
        int callingUid, String callingPackage, String reason) {

        boolean allowed = true;
        if (allowed && mPowerControllerInternal != null) {
            try {
                // 是否函数拦截判断
                allowed = mPowerControllerInternal.judgeAppLaunchAllowed(intent, targetPkg, targetUid, callingUid, callingPackage, reason);
            } catch (Exception e) {}
        }
        return allowed;
    }
    // <-- NOTE: Bug #627645 low power Feature END

}

4. 关联唤醒拦截-send-broadcast类型拦截

  • 源码 frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java
package com.android.server.am;

/**
 * BROADCASTS
 *
 * We keep two broadcast queues and associated bookkeeping, one for those at
 * foreground priority, and one for normal (background-priority) broadcasts.
 */
public final class BroadcastQueue {

    final ActivityManagerService mService;

    final void processNextBroadcast(boolean fromMsg) {
        ...
        if (!skip) {
            skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
                    r.callingPid, r.resolvedType, info.activityInfo.applicationInfo.uid);

            // 拦截位置
            // NOTE: Bug #627645 low power Feature BEG-->
            skip = skip || !mService.judgeStartAllowLocked(r.intent, info.activityInfo.applicationInfo.packageName,
                info.activityInfo.applicationInfo.uid, r.callingUid, r.callerPackage,"send-broadcast");
            // <-- NOTE: Bug #627645 low power Feature END
        }
        ...

5. 关联唤醒拦截-contentprovider类型拦截

  • 源码 frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
package com.android.server.am;

public class ActivityManagerService extends ActivityManagerServiceExAbs
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {

    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
            String name, IBinder token, boolean stable, int userId) {
        
        // 拦截位置
        // NOTE: Bug #627645 low power Feature BEG-->
        String targetPkg = (cpr != null && cpr.appInfo != null) ? cpr.appInfo.packageName : null;
        int targetUid = (cpr != null && cpr.appInfo != null) ? cpr.appInfo.uid : 0;
        if (r != null && r.info != null) {
            String callingPackage = r.info.packageName;
            int callerUid = r.info.uid;
            if(!judgeStartAllowLocked(null, targetPkg, targetUid, callerUid, callingPackage,"contentprovider")) {
                return null;
            }
        }
        // <-- NOTE: Bug #627645 low power Feature END
        // ...
        
        // 其他位置参考
        if (r != null && cpr.canRunHere(r)) {
            // If this is a multiprocess provider, then just return its
            // info and allow the caller to instantiate it.  Only do
            // this if the provider is the same user as the caller's
            // process, or can run as root (so can be in any process).
            return cpr.newHolder(null);
        }

6. 关联唤醒拦截-start-service类型拦截

  • 源码 frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
package com.android.server.am;

public class ActiveServices {
    
    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
        int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
        throws TransactionTooLargeException {
        ...
        // 其他代码位置
        // If this isn't a direct-to-foreground start, check our ability to kick off an
        // arbitrary service
        if (!r.startRequested && !fgRequired) {
            // Before going further -- if this app is not allowed to start services in the
            // background, then at this point we aren't going to let it period.
            final int allowed = mAm.getAppStartModeLocked(r.appInfo.uid, r.packageName,
                    r.appInfo.targetSdkVersion, callingPid, false, false);
            if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
                Slog.w(TAG, "Background start not allowed: service "
                        + service + " to " + r.name.flattenToShortString()
                        + " from pid=" + callingPid + " uid=" + callingUid
                        + " pkg=" + callingPackage);
                if (allowed == ActivityManager.APP_START_MODE_DELAYED) {
                    // In this case we are silently disabling the app, to disrupt as
                    // little as possible existing apps.
                    return null;
                }
                // This app knows it is in the new model where this operation is not
                // allowed, so tell it what has happened.
                UidRecord uidRec = mAm.mActiveUids.get(r.appInfo.uid);
                return new ComponentName("?", "app is in background uid " + uidRec);
            }
        }
        
        // start-service 拦截
        // NOTE: Bug #627645 low power Feature BEG-->
        int targetUid = r.appInfo != null ? r.appInfo.uid : 0 ;
        if(!mAm.judgeStartAllowLocked(service, r.packageName, targetUid, callingUid, callingPackage,"start-service")) {
            return null;
        }
        // <-- NOTE: Bug #627645 low power Feature END
        ...

7. 关联唤醒拦截-bind-service类型拦截

  • 源码 frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
package com.android.server.am;

public class ActiveServices {

    int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
            String resolvedType, final IServiceConnection connection, int flags,
            String callingPackage, final int userId) throws TransactionTooLargeException {
        .....
        // 其他代码位置
        ServiceLookupResult res =
            retrieveServiceLocked(service, resolvedType, callingPackage, Binder.getCallingPid(),
                    Binder.getCallingUid(), userId, true, callerFg, isBindExternal);
        if (res == null) {
            return 0;
        }
        if (res.record == null) {
            return -1;
        }
        ServiceRecord s = res.record;    
        
        // bind-service 拦截
        // NOTE: Bug #627645 low power Feature BEG-->
        String targetPkg = s != null ? s.packageName : null;
        int targetUid = (s != null && s.appInfo != null) ? s.appInfo.uid : 0;
        int callingUid = (callerApp != null && callerApp.info != null) ? callerApp.info.uid : 0;
        if(!mAm.judgeStartAllowLocked(service, targetPkg, targetUid, callingUid, callingPackage,"bind-service")) {
            return 0;
        }
        // <-- NOTE: Bug #627645 low power Feature END
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

法迪

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

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

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

打赏作者

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

抵扣说明:

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

余额充值