Android logFgsBackgroundStart源碼分析

mAllowStartForeground

是否允許后臺啟動前臺Service

// allow the service becomes foreground service? Service started from background may not be
// allowed to become a foreground service.
@PowerExemptionManager.ReasonCode int mAllowStartForeground = REASON_DENIED;

mAllowStartForeground不等于REASON_DENIED,即被允許

((r.mAllowStartForeground != REASON_DENIED) ? "Allowed " : "Disallowed ")

mLoggedInfoAllowStartForeground

// Is the same mInfoAllowStartForeground string has been logged before? Used for dedup.
boolean mLoggedInfoAllowStartForeground;

是否相同的前臺Service被允許或者不被允許從后臺啟動的相關(guān)信息已經(jīng)被記錄過尤蒿。

mInfoAllowStartForeground

// Debug info why mAllowStartForeground is allowed or denied.
String mInfoAllowStartForeground;

存儲被拒絕和被允許的相關(guān)信息

isFgsBgStart

/* Reason code range 10-49 are reserved for BG-FGS-launch allowed proc states */
/** @hide */
public static final int REASON_PROC_STATE_PERSISTENT = 10;
/** @hide */
public static final int REASON_PROC_STATE_PERSISTENT_UI = 11;
/** @hide */
public static final int REASON_PROC_STATE_TOP = 12;
/** @hide */
public static final int REASON_PROC_STATE_BTOP = 13;
/** @hide */
public static final int REASON_PROC_STATE_FGS = 14;
/** @hide */
public static final int REASON_PROC_STATE_BFGS = 15;

預(yù)留10-49狀態(tài)碼颅夺,用于標(biāo)記允許后臺啟動前臺Service的進(jìn)程狀態(tài)。

/* Reason code range 50-99 are reserved for BG-FGS-launch allowed reasons */
/** @hide */
public static final int REASON_UID_VISIBLE = 50;
/** @hide */
public static final int REASON_SYSTEM_UID = 51;
/** @hide */
public static final int REASON_ACTIVITY_STARTER = 52;
/** @hide */
public static final int REASON_START_ACTIVITY_FLAG = 53;
/** @hide */
public static final int REASON_FGS_BINDING = 54;
/** @hide */
public static final int REASON_DEVICE_OWNER = 55;
/** @hide */
public static final int REASON_PROFILE_OWNER = 56;
/** @hide */
public static final int REASON_COMPANION_DEVICE_MANAGER = 57;
/**
 * START_ACTIVITIES_FROM_BACKGROUND permission.
 * @hide
 */
public static final int REASON_BACKGROUND_ACTIVITY_PERMISSION = 58;
/**
 * START_FOREGROUND_SERVICES_FROM_BACKGROUND permission.
 * @hide
 */
public static final int REASON_BACKGROUND_FGS_PERMISSION = 59;

預(yù)留50-99狀態(tài)碼,用于標(biāo)記允許后臺啟動前臺Service的原因。

private static boolean isFgsBgStart(@ReasonCode int code) {
    return code != REASON_PROC_STATE_PERSISTENT
            && code != REASON_PROC_STATE_PERSISTENT_UI
            && code != REASON_PROC_STATE_TOP
            && code != REASON_UID_VISIBLE;
}

isFgsBgStart涮瞻,顧名思義,即前臺Service是否是從后臺啟動的假褪。如果參數(shù)code不等于REASON_PROC_STATE_PERSISTENT署咽、不等于REASON_PROC_STATE_PERSISTENT_UI、不等于REASON_PROC_STATE_TOP嗜价、不等于REASON_UID_VISIBLE艇抠,就認(rèn)為是從后臺啟動的。

// Only log if FGS is started from background.
if (!isFgsBgStart(r.mAllowStartForeground)) {
    return;
}

前臺Service從后臺啟動的時候久锥,才打印日志信息家淤。

Slog.wtfQuiet

/**
 * Similar to {@link #wtf(String, String)}, but does not output anything to the log.
 */
public static void wtfQuiet(@Nullable String tag, @NonNull String msg) {
    Log.wtfQuiet(Log.LOG_ID_SYSTEM, tag, msg, true);
}

wtfQuiet與wtf的區(qū)別有兩個地方:

  1. wtfQuiet是往system日志緩沖區(qū)中寫,wtf是往main日志緩沖區(qū)中寫瑟由。
  2. wtfQuiet不會輸出wtf的日志絮重,wtf會輸出wtf的日志。

mFgsStartAllowedLogSampleRate

/**
 * Sample rate for the allowed FGS start WTF logs.
 *
 * If the value is 0.1, 10% of the logs would be sampled.
 */
volatile float mFgsStartAllowedLogSampleRate = DEFAULT_FGS_START_ALLOWED_LOG_SAMPLE_RATE;

前臺Service被允許從后臺啟動這一事件會被寫到wtf中歹苦,mFgsStartAllowedLogSampleRate管控寫入速度青伤。如果值為0.1,就意味著10%會被記錄殴瘦。

private static final float DEFAULT_FGS_START_ALLOWED_LOG_SAMPLE_RATE = 0.25f; // 25%

默認(rèn)25%的wtf會被記錄狠角。

mFgsStartDeniedLogSampleRate

/**
 * Sample rate for the denied FGS start WTF logs.
 *
 * If the value is 0.1, 10% of the logs would be sampled.
 */
volatile float mFgsStartDeniedLogSampleRate = DEFAULT_FGS_START_DENIED_LOG_SAMPLE_RATE;

前臺Service不被允許從后臺啟動這一事件會被寫到wtf中,mFgsStartDeniedLogSampleRate管控寫入速度蚪腋。如果值為0.1丰歌,就意味著10%會被記錄。

private static final float DEFAULT_FGS_START_DENIED_LOG_SAMPLE_RATE = 1; // 100%

默認(rèn)100%的wtf會被記錄屉凯。

shouldSamplePackageForAtom

/**
 * @return whether a package should be logged, using a random value based on the ANDROID_ID,
 * with a given sampling rate.
 */
public static boolean shouldSamplePackageForAtom(String packageName, float rate) {
    if (rate <= 0) {
        return false;
    }
    if (rate >= 1) {
        return true;
    }
    final int hash = getUnsignedHashCached(packageName) ^ getAndroidIdHash();

    return (((double) hash) / Integer.MAX_VALUE) <= rate;
}

rate如果小于0立帖,則不輸出wtf,如果大于等于1悠砚,則一定會輸出wtf晓勇。后續(xù)算法有點(diǎn)繁雜,就不在這里分析了灌旧。

logFgsBackgroundStart

private void logFgsBackgroundStart(ServiceRecord r) {
    // Only log if FGS is started from background.
    if (!isFgsBgStart(r.mAllowStartForeground)) {
        return;
    }
    if (!r.mLoggedInfoAllowStartForeground) {
        final String msg = "Background started FGS: "
                + ((r.mAllowStartForeground != REASON_DENIED) ? "Allowed " : "Disallowed ")
                + r.mInfoAllowStartForeground;
        if (r.mAllowStartForeground != REASON_DENIED) {
            if (ActivityManagerUtils.shouldSamplePackageForAtom(r.packageName,
                    mAm.mConstants.mFgsStartAllowedLogSampleRate)) {
                Slog.wtfQuiet(TAG, msg);
            }
            Slog.i(TAG, msg);
        } else {
            if (ActivityManagerUtils.shouldSamplePackageForAtom(r.packageName,
                    mAm.mConstants.mFgsStartDeniedLogSampleRate)) {
                Slog.wtfQuiet(TAG, msg);
            }
            Slog.w(TAG, msg);
        }
        r.mLoggedInfoAllowStartForeground = true;
    }
}
  1. 如果前臺Service從后臺啟動的绑咱,則將相關(guān)信息輸出到日志。
  2. 輸出到日志的內(nèi)容有兩類枢泰,一類是wtf羡玛,一類是普通的日志。
  3. 不重復(fù)記錄啟動信息宗苍。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子讳窟,更是在濱河造成了極大的恐慌让歼,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丽啡,死亡現(xiàn)場離奇詭異谋右,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)补箍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門改执,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人坑雅,你說我怎么就攤上這事辈挂。” “怎么了裹粤?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵终蒂,是天一觀的道長。 經(jīng)常有香客問我遥诉,道長拇泣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任矮锈,我火速辦了婚禮霉翔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘苞笨。我一直安慰自己债朵,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布猫缭。 她就那樣靜靜地躺著葱弟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪猜丹。 梳的紋絲不亂的頭發(fā)上芝加,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機(jī)與錄音射窒,去河邊找鬼藏杖。 笑死,一個胖子當(dāng)著我的面吹牛脉顿,可吹牛的內(nèi)容都是我干的蝌麸。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼艾疟,長吁一口氣:“原來是場噩夢啊……” “哼来吩!你這毒婦竟也來了敢辩?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤弟疆,失蹤者是張志新(化名)和其女友劉穎戚长,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體怠苔,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡同廉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了柑司。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片迫肖。...
    茶點(diǎn)故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖攒驰,靈堂內(nèi)的尸體忽然破棺而出蟆湖,到底是詐尸還是另有隱情,我是刑警寧澤讼育,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布帐姻,位于F島的核電站,受9級特大地震影響奶段,放射性物質(zhì)發(fā)生泄漏饥瓷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一痹籍、第九天 我趴在偏房一處隱蔽的房頂上張望呢铆。 院中可真熱鬧,春花似錦蹲缠、人聲如沸棺克。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽娜谊。三九已至,卻和暖如春斤讥,著一層夾襖步出監(jiān)牢的瞬間纱皆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工芭商, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留派草,地道東北人。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓铛楣,卻偏偏與公主長得像近迁,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子簸州,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容