后台启动Activity的源码阅读记录(Android 12版本)

当应用处于后台时,启动Activity有诸多限制,这个主要看AOSP源码中frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java类的shouldAbortBackgroundActivityStart方法

根据源码,后台允许启动Activity的情况如下:

  1. 调用的UID为ROOT_UID、SYSTEM_UID或NFC_UID
if (callingUid == Process.ROOT_UID || callingAppId == Process.SYSTEM_UID
        || callingAppId == Process.NFC_UID) {
    if (DEBUG_ACTIVITY_STARTS) {
        Slog.d(TAG, "Activity start allowed for important callingUid (" + callingUid + ")");
    }
    return false;
}
  1. 调用的APP为Home app
// Always allow home application to start activities.
if (isHomeApp(callingUid, callingPackage)) {
    if (DEBUG_ACTIVITY_STARTS) {
        Slog.d(TAG, "Activity start allowed for home app callingUid (" + callingUid + ")");
    }
    return false;
}
  1. 调用的APP为IME(输入法)
// IME should always be allowed to start activity, like IME settings.
final WindowState imeWindow = mRootWindowContainer.getCurrentInputMethodWindow();
if (imeWindow != null && callingAppId == imeWindow.mOwnerUid) {
    if (DEBUG_ACTIVITY_STARTS) {
        Slog.d(TAG, "Activity start allowed for active ime (" + callingUid + ")");
    }
    return false;
}
  1. 持久化的系统进程或应用有可见窗口
// Normal apps with visible app window will be allowed to start activity if app switching
// is allowed, or apps like live wallpaper with non app visible window will be allowed.
final boolean appSwitchAllowedOrFg =
        appSwitchState == APP_SWITCH_ALLOW || appSwitchState == APP_SWITCH_FG_ONLY;
if (((appSwitchAllowedOrFg || mService.mActiveUids.hasNonAppVisibleWindow(callingUid))
        && callingUidHasAnyVisibleWindow)
        || isCallingUidPersistentSystemProcess) {
    if (DEBUG_ACTIVITY_STARTS) {
        Slog.d(TAG, "Activity start allowed: callingUidHasAnyVisibleWindow = " + callingUid
                + ", isCallingUidPersistentSystemProcess = "
                + isCallingUidPersistentSystemProcess);
    }
    return false;
}
  1. 真实调用方有任何可见窗口
// don't abort if the realCallingUid has a visible window
// TODO(b/171459802): We should check appSwitchAllowed also
if (realCallingUidHasAnyVisibleWindow) {
    if (DEBUG_ACTIVITY_STARTS) {
        Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid
                + ") has visible (non-toast) window");
    }
    return false;
}
  1. 真实调用方为系统进程且允许后台Activity启动
// if the realCallingUid is a persistent system process, abort if the IntentSender
// wasn't allowed to start an activity
if (isRealCallingUidPersistentSystemProcess && allowBackgroundActivityStart) {
    if (DEBUG_ACTIVITY_STARTS) {
        Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid
                + ") is persistent system process AND intent sender allowed "
                + "(allowBackgroundActivityStart = true)");
    }
    return false;
}
  1. 调用方或真实调用方和CompanionApp关联
// don't abort if the realCallingUid is an associated companion app
if (mService.isAssociatedCompanionApp(UserHandle.getUserId(realCallingUid),
        realCallingUid)) {
    if (DEBUG_ACTIVITY_STARTS) {
        Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid
                + ") is companion app");
    }
    return false;
}
// don't abort if the callingUid has companion device
final int callingUserId = UserHandle.getUserId(callingUid);
if (mService.isAssociatedCompanionApp(callingUserId, callingUid)) {
    if (DEBUG_ACTIVITY_STARTS) {
        Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid
                + ") is companion app");
    }
    return false;
}
  1. 调用方有START_ACTIVITIES_FROM_BACKGROUND权限
// don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission
if (mService.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid)
        == PERMISSION_GRANTED) {
    if (DEBUG_ACTIVITY_STARTS) {
        Slog.d(TAG,
                "Background activity start allowed: START_ACTIVITIES_FROM_BACKGROUND "
                        + "permission granted for uid "
                        + callingUid);
    }
    return false;
}
  1. 调用方和最近的组件有相同的uid
// don't abort if the caller has the same uid as the recents component
if (mSupervisor.mRecentTasks.isCallerRecents(callingUid)) {
    if (DEBUG_ACTIVITY_STARTS) {
        Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid
                + ") is recents");
    }
    return false;
}
  1. 调用方是设备拥有者
// don't abort if the callingUid is the device owner
if (mService.isDeviceOwner(callingUid)) {
    if (DEBUG_ACTIVITY_STARTS) {
        Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid
                + ") is device owner");
    }
    return false;
}
  1. 有 SYSTEM_ALERT_WINDOW 权限
// don't abort if the callingUid has SYSTEM_ALERT_WINDOW permission
if (mService.hasSystemAlertWindowPermission(callingUid, callingPid, callingPackage)) {
    Slog.w(TAG, "Background activity start for " + callingPackage
            + " allowed because SYSTEM_ALERT_WINDOW permission is granted.");
    return false;
}
  1. 调用方的app的进程允许从后台启动activity
// don't abort if the callerApp or other processes of that uid are allowed in any way
if (callerApp != null) {
    // first check the original calling process
    if (callerApp.areBackgroundActivityStartsAllowed(appSwitchState)) {
        if (DEBUG_ACTIVITY_STARTS) {
            Slog.d(TAG, "Background activity start allowed: callerApp process (pid = "
                    + callerApp.getPid() + ", uid = " + callerAppUid + ") is allowed");
        }
        return false;
    }
    // only if that one wasn't allowed, check the other ones
    final ArraySet<WindowProcessController> uidProcesses =
            mService.mProcessMap.getProcesses(callerAppUid);
    if (uidProcesses != null) {
        for (int i = uidProcesses.size() - 1; i >= 0; i--) {
            final WindowProcessController proc = uidProcesses.valueAt(i);
            if (proc != callerApp
                    && proc.areBackgroundActivityStartsAllowed(appSwitchState)) {
                if (DEBUG_ACTIVITY_STARTS) {
                    Slog.d(TAG,
                            "Background activity start allowed: process " + proc.getPid()
                                    + " from uid " + callerAppUid + " is allowed");
                }
                return false;
            }
        }
    }
}

你可能感兴趣的:(杂文记录,android,java,后台Activity,background)