Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 466607f6 authored by Jing Ji's avatar Jing Ji Committed by Automerger Merge Worker
Browse files

Merge "Fix potential overflow with casting long to int in AppExitInfoTracker"...

Merge "Fix potential overflow with casting long to int in AppExitInfoTracker" into sc-dev am: 6d3b5033

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14848023

Change-Id: I77c5458a5a859c641fb4e9089c3dd6bf128c1483
parents 17a7a977 6d3b5033
Loading
Loading
Loading
Loading
+13 −10
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;

import android.annotation.CurrentTimeMillisLong;
import android.annotation.Nullable;
import android.app.ApplicationExitInfo;
import android.app.ApplicationExitInfo.Reason;
@@ -287,8 +288,8 @@ public final class AppExitInfoTracker {
        if (!mAppExitInfoLoaded.get()) {
            return;
        }
        mKillHandler.obtainMessage(KillHandler.MSG_PROC_DIED, obtainRawRecord(app))
                .sendToTarget();
        mKillHandler.obtainMessage(KillHandler.MSG_PROC_DIED,
                obtainRawRecord(app, System.currentTimeMillis())).sendToTarget();
    }

    void scheduleNoteAppKill(final ProcessRecord app, final @Reason int reason,
@@ -300,7 +301,7 @@ public final class AppExitInfoTracker {
            return;
        }

        ApplicationExitInfo raw = obtainRawRecord(app);
        ApplicationExitInfo raw = obtainRawRecord(app, System.currentTimeMillis());
        raw.setReason(reason);
        raw.setSubReason(subReason);
        raw.setDescription(msg);
@@ -542,7 +543,8 @@ public final class AppExitInfoTracker {
                        return AppExitInfoTracker.FOREACH_ACTION_NONE;
                    });

                    Collections.sort(list, (a, b) -> (int) (b.getTimestamp() - a.getTimestamp()));
                    Collections.sort(list,
                            (a, b) -> Long.compare(b.getTimestamp(), a.getTimestamp()));
                    int size = list.size();
                    if (maxNum > 0) {
                        size = Math.min(size, maxNum);
@@ -976,7 +978,7 @@ public final class AppExitInfoTracker {
    }

    @VisibleForTesting
    ApplicationExitInfo obtainRawRecord(ProcessRecord app) {
    ApplicationExitInfo obtainRawRecord(ProcessRecord app, @CurrentTimeMillisLong long timestamp) {
        ApplicationExitInfo info = mRawRecordsPool.acquire();
        if (info == null) {
            info = new ApplicationExitInfo();
@@ -998,7 +1000,7 @@ public final class AppExitInfoTracker {
            info.setImportance(procStateToImportance(app.mState.getSetProcState()));
            info.setPss(app.mProfile.getLastPss());
            info.setRss(app.mProfile.getLastRss());
            info.setTimestamp(System.currentTimeMillis());
            info.setTimestamp(timestamp);
        }

        return info;
@@ -1298,7 +1300,7 @@ public final class AppExitInfoTracker {
                        results.add(mInfos.valueAt(i));
                    }
                    Collections.sort(results,
                            (a, b) -> (int) (b.getTimestamp() - a.getTimestamp()));
                            (a, b) -> Long.compare(b.getTimestamp(), a.getTimestamp()));
                } else {
                    if (maxNum == 1) {
                        // Most of the caller might be only interested with the most recent one
@@ -1318,7 +1320,7 @@ public final class AppExitInfoTracker {
                            list.add(mInfos.valueAt(i));
                        }
                        Collections.sort(list,
                                (a, b) -> (int) (b.getTimestamp() - a.getTimestamp()));
                                (a, b) -> Long.compare(b.getTimestamp(), a.getTimestamp()));
                        for (int i = 0; i < maxNum; i++) {
                            results.add(list.get(i));
                        }
@@ -1412,7 +1414,7 @@ public final class AppExitInfoTracker {
            for (int i = mInfos.size() - 1; i >= 0; i--) {
                list.add(mInfos.valueAt(i));
            }
            Collections.sort(list, (a, b) -> (int) (b.getTimestamp() - a.getTimestamp()));
            Collections.sort(list, (a, b) -> Long.compare(b.getTimestamp(), a.getTimestamp()));
            int size = list.size();
            for (int i = 0; i < size; i++) {
                list.get(i).dump(pw, prefix + "  ", "#" + i, sdf);
@@ -1629,7 +1631,8 @@ public final class AppExitInfoTracker {
        }
    }

    private static boolean isFresh(long timestamp) {
    @VisibleForTesting
    boolean isFresh(long timestamp) {
        // A process could be dying but being stuck in some state, i.e.,
        // being TRACED by tombstoned, thus the zygote receives SIGCHILD
        // way after we already knew the kill (maybe because we did the kill :P),
+27 −24
Original line number Diff line number Diff line
@@ -36,10 +36,12 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;

import android.annotation.CurrentTimeMillisLong;
import android.app.ApplicationExitInfo;
import android.content.ComponentName;
import android.content.Context;
@@ -163,14 +165,15 @@ public class ApplicationExitInfoTest {
        }
    }

    private void updateExitInfo(ProcessRecord app) {
        ApplicationExitInfo raw = mAppExitInfoTracker.obtainRawRecord(app);
    private void updateExitInfo(ProcessRecord app, @CurrentTimeMillisLong long timestamp) {
        ApplicationExitInfo raw = mAppExitInfoTracker.obtainRawRecord(app, timestamp);
        mAppExitInfoTracker.handleNoteProcessDiedLocked(raw);
        mAppExitInfoTracker.recycleRawRecord(raw);
    }

    private void noteAppKill(ProcessRecord app, int reason, int subReason, String msg) {
        ApplicationExitInfo raw = mAppExitInfoTracker.obtainRawRecord(app);
    private void noteAppKill(ProcessRecord app, int reason, int subReason, String msg,
            @CurrentTimeMillisLong long timestamp) {
        ApplicationExitInfo raw = mAppExitInfoTracker.obtainRawRecord(app, timestamp);
        raw.setReason(reason);
        raw.setSubReason(subReason);
        raw.setDescription(msg);
@@ -190,6 +193,7 @@ public class ApplicationExitInfoTest {

        // Test application calls System.exit()
        doNothing().when(mAppExitInfoTracker).schedulePersistProcessExitInfo(anyBoolean());
        doReturn(true).when(mAppExitInfoTracker).isFresh(anyLong());

        final int app1Uid = 10123;
        final int app1Pid1 = 12345;
@@ -216,7 +220,7 @@ public class ApplicationExitInfoTest {
        final byte[] app1Cookie2 = {(byte) 0x08, (byte) 0x07, (byte) 0x06, (byte) 0x05,
                (byte) 0x04, (byte) 0x03, (byte) 0x02, (byte) 0x01};

        final long now1 = System.currentTimeMillis();
        final long now1 = 1;
        ProcessRecord app = makeProcessRecord(
                app1Pid1,                    // pid
                app1Uid,                     // uid
@@ -240,7 +244,7 @@ public class ApplicationExitInfoTest {
        doReturn(null)
                .when(mAppExitInfoTracker.mAppExitInfoSourceLmkd)
                .remove(anyInt(), anyInt());
        updateExitInfo(app);
        updateExitInfo(app, now1);

        ArrayList<ApplicationExitInfo> list = new ArrayList<ApplicationExitInfo>();
        mAppExitInfoTracker.getExitInfo(app1PackageName, app1Uid, app1Pid1, 0, list);
@@ -290,11 +294,11 @@ public class ApplicationExitInfoTest {
                .when(mAppExitInfoTracker.mAppExitInfoSourceLmkd)
                .remove(anyInt(), anyInt());
        noteAppKill(app, ApplicationExitInfo.REASON_USER_REQUESTED,
                ApplicationExitInfo.SUBREASON_UNKNOWN, null);
                ApplicationExitInfo.SUBREASON_UNKNOWN, null, now1s);

        // Case 2: create another app1 process record with a different pid
        sleep(1);
        final long now2 = System.currentTimeMillis();
        final long now2 = 2;
        app = makeProcessRecord(
                app1Pid2,               // pid
                app1Uid,                // uid
@@ -316,16 +320,15 @@ public class ApplicationExitInfoTest {
        doReturn(new Pair<Long, Object>(now2, Integer.valueOf(makeExitStatus(exitCode))))
                .when(mAppExitInfoTracker.mAppExitInfoSourceZygote)
                .remove(anyInt(), anyInt());
        updateExitInfo(app);
        updateExitInfo(app, now2);
        list.clear();

        // Get all the records for app1Uid
        mAppExitInfoTracker.getExitInfo(null, app1Uid, 0, 0, list);
        assertEquals(3, list.size());

        info = list.get(0);
        info = list.get(1);

        // Verify the most recent one
        verifyApplicationExitInfo(
                info,                                 // info
                now2,                                 // timestamp
@@ -346,7 +349,7 @@ public class ApplicationExitInfoTest {
        assertTrue(ArrayUtils.equals(info.getProcessStateSummary(), app1Cookie2,
                app1Cookie2.length));

        info = list.get(1);
        info = list.get(0);
        verifyApplicationExitInfo(
                info,                                      // info
                now1s,                                     // timestamp
@@ -386,7 +389,7 @@ public class ApplicationExitInfoTest {
        doReturn(new Pair<Long, Object>(now3, Integer.valueOf(makeSignalStatus(sigNum))))
                .when(mAppExitInfoTracker.mAppExitInfoSourceZygote)
                .remove(anyInt(), anyInt());
        updateExitInfo(app);
        updateExitInfo(app, now3);
        list.clear();
        mAppExitInfoTracker.getExitInfo(app1PackageName, app1UidUser2, app1PidUser2, 0, list);

@@ -463,7 +466,7 @@ public class ApplicationExitInfoTest {
                app2Rss1,                    // rss
                app2ProcessName,             // processName
                app2PackageName);            // packageName
        updateExitInfo(app);
        updateExitInfo(app, now4);
        list.clear();
        mAppExitInfoTracker.getExitInfo(app2PackageName, app2UidUser2, app2PidUser2, 0, list);
        assertEquals(1, list.size());
@@ -523,9 +526,9 @@ public class ApplicationExitInfoTest {
                app3ProcessName,         // processName
                app3PackageName);        // packageName
        noteAppKill(app, ApplicationExitInfo.REASON_CRASH_NATIVE,
                ApplicationExitInfo.SUBREASON_UNKNOWN, app3Description);
                ApplicationExitInfo.SUBREASON_UNKNOWN, app3Description, now5);

        updateExitInfo(app);
        updateExitInfo(app, now5);
        list.clear();
        mAppExitInfoTracker.getExitInfo(app3PackageName, app3UidUser2, app3PidUser2, 0, list);
        assertEquals(1, list.size());
@@ -648,11 +651,11 @@ public class ApplicationExitInfoTest {
                app3PackageName);            // packageName
        mAppExitInfoTracker.mIsolatedUidRecords.addIsolatedUid(app3IsolatedUid, app3Uid);
        noteAppKill(app, ApplicationExitInfo.REASON_CRASH,
                ApplicationExitInfo.SUBREASON_UNKNOWN, app3Description2);
                ApplicationExitInfo.SUBREASON_UNKNOWN, app3Description2, now6);

        assertEquals(app3Uid, mAppExitInfoTracker.mIsolatedUidRecords
                .getUidByIsolatedUid(app3IsolatedUid).longValue());
        updateExitInfo(app);
        updateExitInfo(app, now6);
        assertNull(mAppExitInfoTracker.mIsolatedUidRecords.getUidByIsolatedUid(app3IsolatedUid));

        list.clear();
@@ -736,9 +739,9 @@ public class ApplicationExitInfoTest {

        mAppExitInfoTracker.mIsolatedUidRecords.addIsolatedUid(app1IsolatedUidUser2, app1UidUser2);
        noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
                ApplicationExitInfo.SUBREASON_UNKNOWN, app1Description);
                ApplicationExitInfo.SUBREASON_UNKNOWN, app1Description, now8);

        updateExitInfo(app);
        updateExitInfo(app, now8);
        list.clear();
        mAppExitInfoTracker.getExitInfo(app1PackageName, app1UidUser2, app1PidUser2, 1, list);
        assertEquals(1, list.size());
@@ -802,8 +805,8 @@ public class ApplicationExitInfoTest {
                traceFile, traceStart, traceEnd);

        noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
                ApplicationExitInfo.SUBREASON_TOO_MANY_EMPTY, app1Description2);
        updateExitInfo(app);
                ApplicationExitInfo.SUBREASON_TOO_MANY_EMPTY, app1Description2, now9);
        updateExitInfo(app, now9);
        list.clear();
        mAppExitInfoTracker.getExitInfo(app1PackageName, app1UidUser2, app1Pid2User2, 1, list);
        assertEquals(1, list.size());
@@ -859,7 +862,7 @@ public class ApplicationExitInfoTest {
        mAppExitInfoTracker.getExitInfo(null, app1Uid, 0, 0, list);
        assertEquals(3, list.size());

        info = list.get(0);
        info = list.get(1);

        exitCode = 6;
        verifyApplicationExitInfo(
@@ -879,7 +882,7 @@ public class ApplicationExitInfoTest {
                IMPORTANCE_SERVICE,                   // importance
                null);                                // description

        info = list.get(1);
        info = list.get(0);
        verifyApplicationExitInfo(
                info,                                      // info
                now1s,                                     // timestamp