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

Commit 42cda495 authored by Vova Sharaienko's avatar Vova Sharaienko
Browse files

AMS: added caching DataInputStream object

DataInputStream is cached for the lmkd socket communication
Since the LmkdConnection ByteBuffer is allocated once,
no need to dynamically allocate DataInputStream,
just do a reset() before using

Bug: 184698933
Test: lmkd_unit_test - test check_for_oom tests lmkd message send to AMS
Test: statsd_testdrive 51 54 to inspect statsd logged atoms data
Change-Id: I9b65d82618654d59236c79be8cd8da66bc90c91c
parent 26df817b
Loading
Loading
Loading
Loading
+31 −19
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@ import com.android.internal.annotations.GuardedBy;

import libcore.io.IoUtils;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
@@ -74,7 +76,7 @@ public class LmkdConnection {
         * @param receivedLen Size of the data received
         * @return True if the message has been handled correctly, false otherwise.
         */
        boolean handleUnsolicitedMessage(ByteBuffer dataReceived, int receivedLen);
        boolean handleUnsolicitedMessage(DataInputStream inputData, int receivedLen);
    }

    private final MessageQueue mMsgQueue;
@@ -99,6 +101,10 @@ public class LmkdConnection {
    private final ByteBuffer mInputBuf =
            ByteBuffer.allocate(LMKD_REPLY_MAX_SIZE);

    // Input stream to parse the incoming data
    private final DataInputStream mInputData = new DataInputStream(
            new ByteArrayInputStream(mInputBuf.array()));

    // object to protect mReplyBuf and to wait/notify when reply is received
    private final Object mReplyBufLock = new Object();

@@ -190,6 +196,9 @@ public class LmkdConnection {
    private void processIncomingData() {
        int len = read(mInputBuf);
        if (len > 0) {
            try {
                // reset InputStream to point into mInputBuf.array() begin
                mInputData.reset();
                synchronized (mReplyBufLock) {
                    if (mReplyBuf != null) {
                        if (mListener.isReplyExpected(mReplyBuf, mInputBuf, len)) {
@@ -198,19 +207,22 @@ public class LmkdConnection {
                            mReplyBuf.rewind();
                            // wakeup the waiting thread
                            mReplyBufLock.notifyAll();
                    } else if (!mListener.handleUnsolicitedMessage(mInputBuf, len)) {
                        } else if (!mListener.handleUnsolicitedMessage(mInputData, len)) {
                            // received unexpected packet
                            // treat this as an error
                            mReplyBuf = null;
                            mReplyBufLock.notifyAll();
                            Slog.e(TAG, "Received an unexpected packet from lmkd");
                        }
                } else if (!mListener.handleUnsolicitedMessage(mInputBuf, len)) {
                    } else if (!mListener.handleUnsolicitedMessage(mInputData, len)) {
                        // received asynchronous communication from lmkd
                        // but we don't recognize it.
                        Slog.w(TAG, "Received an unexpected packet from lmkd");
                    }
                }
            } catch (IOException e) {
                Slog.e(TAG, "Failed to parse lmkd data buffer. Size = " + len);
            }
        }
    }

+1 −8
Original line number Diff line number Diff line
@@ -23,10 +23,8 @@ import android.util.Slog;

import com.android.internal.util.FrameworkStatsLog;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;

/**
 * Activity manager communication with lmkd data handling and statsd atom logging
@@ -51,13 +49,8 @@ public final class LmkdStatsReporter {
     * Logs the event when LMKD kills a process to reduce memory pressure.
     * Code: LMK_KILL_OCCURRED = 51
     */
    public static void logKillOccurred(ByteBuffer dataReceived) {
        DataInputStream inputData = new DataInputStream(
                new ByteArrayInputStream(dataReceived.array()));

    public static void logKillOccurred(DataInputStream inputData) {
        try {
            //read first int which denotes the message type
            final int msgType = inputData.readInt();
            final long pgFault = inputData.readLong();
            final long pgMajFault = inputData.readLong();
            final long rssInBytes = inputData.readLong();
+32 −24
Original line number Diff line number Diff line
@@ -139,6 +139,7 @@ import com.android.server.wm.WindowProcessController;

import dalvik.system.VMRuntime;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -835,37 +836,44 @@ public final class ProcessList {
                        }

                        @Override
                        public boolean handleUnsolicitedMessage(ByteBuffer dataReceived,
                        public boolean handleUnsolicitedMessage(DataInputStream inputData,
                                int receivedLen) {
                            if (receivedLen < 4) {
                                return false;
                            }

                            switch (dataReceived.getInt(0)) {
                            try {
                                switch (inputData.readInt()) {
                                    case LMK_PROCKILL:
                                        if (receivedLen != 12) {
                                            return false;
                                        }
                                    mAppExitInfoTracker.scheduleNoteLmkdProcKilled(
                                            dataReceived.getInt(4), dataReceived.getInt(8));
                                        final int pid = inputData.readInt();
                                        final int uid = inputData.readInt();
                                        mAppExitInfoTracker.scheduleNoteLmkdProcKilled(pid, uid);
                                        return true;
                                    case LMK_KILL_OCCURRED:
                                    if (receivedLen < LmkdStatsReporter.KILL_OCCURRED_MSG_SIZE) {
                                        if (receivedLen
                                                < LmkdStatsReporter.KILL_OCCURRED_MSG_SIZE) {
                                            return false;
                                        }
                                    dataReceived.position(4);
                                    LmkdStatsReporter.logKillOccurred(dataReceived);
                                        LmkdStatsReporter.logKillOccurred(inputData);
                                        return true;
                                    case LMK_STATE_CHANGED:
                                    if (receivedLen != LmkdStatsReporter.STATE_CHANGED_MSG_SIZE) {
                                        if (receivedLen
                                                != LmkdStatsReporter.STATE_CHANGED_MSG_SIZE) {
                                            return false;
                                        }
                                    LmkdStatsReporter.logStateChanged(
                                            dataReceived.getInt(4));
                                        final int state = inputData.readInt();
                                        LmkdStatsReporter.logStateChanged(state);
                                        return true;
                                    default:
                                        return false;
                                }
                            } catch (IOException e) {
                                Slog.e(TAG, "Invalid buffer data. Failed to log LMK_KILL_OCCURRED");
                            }
                            return false;
                        }
                    }
            );