Cached_app_freezer 流程分析

概述:cached app freezer 是将原本需要不可见的随时可以被清理的Activity,进行冻结, 在下次使用时解冻, 从面提升系统保活能力.

开发者选项中开启的入口:

development_settings.xml

<ListPreference
    android:key="cached_apps_freezer"
    android:title="@string/cached_apps_freezer"
    android:entries="@array/cached_apps_freezer_entries"
    android:entryValues="@array/cached_apps_freezer_values" />

设置中开启cached app freezer 功能

CachedAppsFreezerPreferenceController.java

private DialogInterface.OnClickListener getRebootDialogOkListener(Object newValue) {
        return (dialog, which) -> {
            Settings.Global.putString(mContext.getContentResolver(),
                    Settings.Global.CACHED_APPS_FREEZER_ENABLED,
                    newValue.toString());

            updateState(mPreference);

            PowerManager pm = mContext.getSystemService(PowerManager.class);
            pm.reboot(null);
        };
    }

App Freeze 启用流程

CachedAppOptimizer.java

mAm.mHandler.post(() -> {
        if (useFreezer) {
            Slog.d(TAG_AM, "Freezer enabled");
            enableFreezer(true);

            if (!mCachedAppOptimizerThread.isAlive()) {
                mCachedAppOptimizerThread.start();
            }

            if (mFreezeHandler == null) {
                mFreezeHandler = new FreezeHandler();
            }

            Process.setThreadGroupAndCpuset(mCachedAppOptimizerThread.getThreadId(),
                    Process.THREAD_GROUP_SYSTEM);
        } else {
            Slog.d(TAG_AM, "Freezer disabled");
            enableFreezer(false);
        }
    });
}

冻结进程

private void freezeProcess(final ProcessRecord proc) {
    int pid = proc.getPid(); // Unlocked intentionally
    final String name = proc.processName;
    final long unfrozenDuration;
    final boolean frozen;
    final ProcessCachedOptimizerRecord opt = proc.mOptRecord;

    opt.setPendingFreeze(false);

    try {
        // pre-check for locks to avoid unnecessary freeze/unfreeze operations
        if (mProcLocksReader.hasFileLocks(pid)) {
            if (DEBUG_FREEZER) {
                Slog.d(TAG_AM, name + " (" + pid + ") holds file locks, not freezing");
            }
            return;
        }
    } catch (Exception e) {
        Slog.e(TAG_AM, "Not freezing. Unable to check file locks for " + name + "(" + pid
                + "): " + e);
        return;
    }

    synchronized (mProcLock) {
        pid = proc.getPid();
        if (proc.mState.getCurAdj() < ProcessList.CACHED_APP_MIN_ADJ
                || opt.shouldNotFreeze()) {
            if (DEBUG_FREEZER) {
                Slog.d(TAG_AM, "Skipping freeze for process " + pid
                        + " " + name + " curAdj = " + proc.mState.getCurAdj()
                        + ", shouldNotFreeze = " + opt.shouldNotFreeze());
            }
            return;
        }

        if (mFreezerOverride) {
            opt.setFreezerOverride(true);
            Slog.d(TAG_AM, "Skipping freeze for process " + pid
                    + " " + name + " curAdj = " + proc.mState.getCurAdj()
                    + "(override)");
            return;
        }

        if (pid == 0 || opt.isFrozen()) {
            // Already frozen or not a real process, either one being
            // launched or one being killed
            return;
        }

        // Freeze binder interface before the process, to flush any
        // transactions that might be pending.
        try {
            freezeBinder(pid, true);
        } catch (RuntimeException e) {
            Slog.e(TAG_AM, "Unable to freeze binder for " + pid + " " + name);
            mFreezeHandler.post(() -> {
                synchronized (mAm) {
                    proc.killLocked("Unable to freeze binder interface",
                            ApplicationExitInfo.REASON_OTHER,
                            ApplicationExitInfo.SUBREASON_FREEZER_BINDER_IOCTL, true);
                }
            });
        }

        long unfreezeTime = opt.getFreezeUnfreezeTime();

        try {
            Process.setProcessFrozen(pid, proc.uid, true);

            opt.setFreezeUnfreezeTime(SystemClock.uptimeMillis());
            opt.setFrozen(true);
        } catch (Exception e) {
            Slog.w(TAG_AM, "Unable to freeze " + pid + " " + name);
        }

        unfrozenDuration = opt.getFreezeUnfreezeTime() - unfreezeTime;
        frozen = opt.isFrozen();
    }

    if (!frozen) {
        return;
    }

    Slog.d(TAG_AM, "froze " + pid + " " + name);

    EventLog.writeEvent(EventLogTags.AM_FREEZE, pid, name);

    // See above for why we're not taking mPhenotypeFlagLock here
    if (mRandom.nextFloat() < mFreezerStatsdSampleRate) {
        FrameworkStatsLog.write(FrameworkStatsLog.APP_FREEZE_CHANGED,
                FrameworkStatsLog.APP_FREEZE_CHANGED__ACTION__FREEZE_APP,
                pid,
                name,
                unfrozenDuration);
    }

    try {
        // post-check to prevent races
        if (mProcLocksReader.hasFileLocks(pid)) {
            if (DEBUG_FREEZER) {
                Slog.d(TAG_AM, name + " (" + pid + ") holds file locks, reverting freeze");
            }

            synchronized (mAm) {
                synchronized (mProcLock) {
                    unfreezeAppLSP(proc);
                }
            }
        }
    } catch (Exception e) {
        Slog.e(TAG_AM, "Unable to check file locks for " + name + "(" + pid + "): " + e);
        synchronized (mAm) {
            synchronized (mProcLock) {
                unfreezeAppLSP(proc);
            }
        }
    }
}

通过 Process.setProcessFrozen(pid, proc.uid, true); 来冻结目标进程

//TODO

// native层冻结原理分析

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值