Android power on skip ANR

Posted by tendrousbeastie on Tue, 07 Jan 2020 06:36:39 +0100

1. reasons

In some low-end mobile chips, it will be found that when the power on wizard is turned on, it is easy to have various situations of gms application of anr, which is caused by high cpu. However, for chips with poor performance, it is easy to cause anr, so the solution 1 is to skip skip anr.

2. Judgment time

Search add start, add end

xref: /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

final void finishBooting() {
        ...
        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
            // Start looking for apps that are abusing wake locks.
            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);

            /// M: AMEventHook event @{
            AMEventHookData.BeforeSendBootCompleted eventData =
                AMEventHookData.BeforeSendBootCompleted.createInstance();
            AMEventHookResult eventResult =
                mAMEventHook.hook(AMEventHook.Event.AM_BeforeSendBootCompleted,
                    eventData);
            if (AMEventHookResult.hasAction(eventResult,
                AMEventHookAction.AM_Interrupt)) {
                return;
            }
            /// M: AMEventHook event @}

            /// M: AMS log enhancement @{
            Slog.v(TAG, "broadcast BOOT_COMPLETED intent");
            /// @}

            // Tell anyone interested that we are done booting!
            SystemProperties.set("sys.boot_completed", "1");

            //add start, set boot_completed_time (in ms) to property
            SystemProperties.set("sys.boot_completed_time", String.valueOf(SystemClock.uptimeMillis()));
            Slog.d(TAG, "set sys.boot_completed_time = " + String.valueOf(SystemClock.uptimeMillis()));
            // add end 

            // And trigger dev.bootcomplete if we are not showing encryption progress
            if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
                || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
                SystemProperties.set("dev.bootcomplete", "1");
            }
            ...
        }
    }
    /// M: ANR debug mechanism for defer ANR @{
    /// M: Inform ANR manager boot completed
    mANRManager.writeEvent(ANRManager.EVENT_BOOT_COMPLETED);
    /// M: ANR debug mechanism for defer ANR @}
}




/frameworks/base/services/core/java/com/android/server/am/AppErrors.java
    void stopReportingCrashesLocked(ProcessRecord proc) {
        if (mAppsNotReportingCrashes == null) {
            mAppsNotReportingCrashes = new ArraySet<>();
        }
        mAppsNotReportingCrashes.add(proc.info.packageName);
    }

    //add start, boot completed time < 5min, skip anr
    boolean isBootCompletedLongEnough(long duration) {
        if ("1".equals(SystemProperties.get("sys.boot_completed"))) {// boot completed
            String completedTimeString = SystemProperties.get("sys.boot_completed_time");
            long expectedTime = Long.parseLong(completedTimeString) + duration;
            long currTime = SystemClock.uptimeMillis();
            Slog.d(TAG, "expectedTime = " + expectedTime + ", currTime = " + currTime);
            return currTime > expectedTime;
        }
        return false;
    }
    //add end

    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
            ActivityRecord parent, boolean aboveSystem, final String annotation) {

        /// M: ANR debug mechanism for skip ANR @{
        if (mService.mANRManager.isANRFlowSkipped(app.pid, app.processName, annotation,
                mService.mShuttingDown, app.notResponding, app.crashing) == true) {
            return;
        }
        /// M: ANR debug mechanism for skip ANR @}

        //Skip the anr caused by local "changed" within 5 minutes after power on, here you can change the conditions
        //add start, boot completed time < 5min, skip anr
        if (!isBootCompletedLongEnough(5 * 1000 * 60) && annotation != null 
            && annotation.contains("android.intent.action.LOCALE_CHANGED")) {
            Slog.d(TAG, "skip anr when booting");
            return;
        }
        //add end

        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
        ... 
    }

3. Another CPU solution

Because of the problem caused by high cpu occupation, all cpu core s can run when the power is turned on, and the cpu frequency can be restored when the power is turned on

For example, write the cpu node in init.rc to raise the frequency, and then use the on command in RC to

//You can also customize attributes to operate
on boot
    write /sys/devices/system/cpu/cpufreq/interactive/target_loads 0 //Rising frequency

on property:sys.boot_completed=1
    write /sys/devices/system/cpu/cpufreq/interactive/target_loads 1  //Restore cpu

 

Topics: Java Android Mobile