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

Commit 8b901f01 authored by Carlos Galo's avatar Carlos Galo Committed by Gerrit Code Review
Browse files

Merge changes from topic "oom-ams-subreason" into main

* changes:
  servicestest: add jni dependency
  mockingservicestest: adding jni dependency for OomConnection
  Add out-of-memory (OOM) kills to ApplicationExitInfo
parents f4747fba babb9220
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -460,6 +460,15 @@ public final class ApplicationExitInfo implements Parcelable {
     */
    public static final int SUBREASON_SDK_SANDBOX_NOT_NEEDED = 28;

    /**
     * The process was killed by the [kernel] Out-of-memory (OOM) killer; this
     * would be set only when the reason is {@link #REASON_LOW_MEMORY}.
     *
     * For internal use only.
     * @hide
     */
    public static final int SUBREASON_OOM_KILL = 30;

    // If there is any OEM code which involves additional app kill reasons, it should
    // be categorized in {@link #REASON_OTHER}, with subreason code starting from 1000.

@@ -635,6 +644,7 @@ public final class ApplicationExitInfo implements Parcelable {
        SUBREASON_KILL_BACKGROUND,
        SUBREASON_PACKAGE_UPDATE,
        SUBREASON_UNDELIVERED_BROADCAST,
        SUBREASON_OOM_KILL,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface SubReason {}
@@ -1360,6 +1370,8 @@ public final class ApplicationExitInfo implements Parcelable {
                return "PACKAGE UPDATE";
            case SUBREASON_UNDELIVERED_BROADCAST:
                return "UNDELIVERED BROADCAST";
            case SUBREASON_OOM_KILL:
                return "OOM KILL";
            default:
                return "UNKNOWN";
        }
+63 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.os;


/**
 * Expected data to get back from the OOM event's file.
 * Note that this should be equivalent to the struct <b>OomKill</b> inside
 * <pre>
 * system/memory/libmeminfo/libmemevents/include/memevents.h
 * </pre>
 *
 * @hide
 */
public final class OomKillRecord {
    private long mTimeStampInMillis;
    private int mPid;
    private int mUid;
    private String mProcessName;
    private short mOomScoreAdj;

    public OomKillRecord(long timeStampInMillis, int pid, int uid,
                            String processName, short oomScoreAdj) {
        this.mTimeStampInMillis = timeStampInMillis;
        this.mPid = pid;
        this.mUid = uid;
        this.mProcessName = processName;
        this.mOomScoreAdj = oomScoreAdj;
    }

    public long getTimestampMilli() {
        return mTimeStampInMillis;
    }

    public int getPid() {
        return mPid;
    }

    public int getUid() {
        return mUid;
    }

    public String getProcessName() {
        return mProcessName;
    }

    public short getOomScoreAdj() {
        return mOomScoreAdj;
    }
}
+63 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.am;

import android.os.OomKillRecord;
import android.util.Slog;

/** Connection to the out-of-memory (OOM) events' file */
public final class OomConnection {
    private static final String TAG = "OomConnection";

    /** Connection listener interface */
    public interface OomConnectionListener {

        /**
         * Callback function to handle the newest OOM kills.
         *
         * @param oomKills List of oom kills received from `waitOom()`
         */
        void handleOomEvent(OomKillRecord[] oomKills);
    }

    private final OomConnectionListener mOomListener;

    private final OomConnectionThread mOomConnectionThread;

    private static native OomKillRecord[] waitOom();

    public OomConnection(OomConnectionListener listener) {
        mOomListener = listener;
        mOomConnectionThread = new OomConnectionThread();
        mOomConnectionThread.start();
    }

    private final class OomConnectionThread extends Thread {
        public void run() {
            while (true) {
                OomKillRecord[] oom_kills = null;
                try {
                    oom_kills = waitOom();
                    mOomListener.handleOomEvent(oom_kills);
                } catch (RuntimeException e) {
                    Slog.e(TAG, "failed waiting for OOM events: " + e);
                    break;
                }
            }
        }
    }
}
+18 −0
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.OomKillRecord;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteCallbackList;
@@ -412,6 +413,8 @@ public final class ProcessList {

    private static LmkdConnection sLmkdConnection = null;

    private static OomConnection sOomConnection = null;

    private boolean mOomLevelsSet = false;

    private boolean mAppDataIsolationEnabled = false;
@@ -855,6 +858,21 @@ public final class ProcessList {
                    THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
            sKillThread.start();
            sKillHandler = new KillHandler(sKillThread.getLooper());
            sOomConnection = new OomConnection(new OomConnection.OomConnectionListener() {
                @Override
                public void handleOomEvent(OomKillRecord[] oomKills) {
                    for (OomKillRecord oomKill: oomKills) {
                        synchronized (mProcLock) {
                            noteAppKill(
                                oomKill.getPid(),
                                oomKill.getUid(),
                                ApplicationExitInfo.REASON_LOW_MEMORY,
                                ApplicationExitInfo.SUBREASON_OOM_KILL,
                                "oom");
                        }
                    }
                }
            });
            sLmkdConnection = new LmkdConnection(sKillThread.getLooper().getQueue(),
                    new LmkdConnection.LmkdConnectionListener() {
                        @Override
+7 −0
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ cc_library_static {
        "onload.cpp",
        ":lib_cachedAppOptimizer_native",
        ":lib_gameManagerService_native",
        ":lib_oomConnection_native",
    ],

    include_dirs: [
@@ -118,6 +119,7 @@ cc_defaults {
        "libhardware_legacy",
        "libhidlbase",
        "libmeminfo",
        "libmemevents",
        "libmemtrackproxy",
        "libmtp",
        "libnativehelper",
@@ -235,3 +237,8 @@ filegroup {
        "com_android_server_app_GameManagerService.cpp",
    ],
}

filegroup {
    name: "lib_oomConnection_native",
    srcs: ["com_android_server_am_OomConnection.cpp"],
}
Loading