19709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon/*
29709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon * Copyright (C) 2017 The Android Open Source Project
39709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon *
49709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon * Licensed under the Apache License, Version 2.0 (the "License");
59709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon * you may not use this file except in compliance with the License.
69709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon * You may obtain a copy of the License at
79709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon *
89709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon *      http://www.apache.org/licenses/LICENSE-2.0
99709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon *
109709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon * Unless required by applicable law or agreed to in writing, software
119709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon * distributed under the License is distributed on an "AS IS" BASIS,
129709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon * See the License for the specific language governing permissions and
149709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon * limitations under the License.
159709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon */
169709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafonpackage com.android.statsd.loadtest;
179709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon
189709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafonimport android.annotation.Nullable;
199709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafonimport android.os.SystemClock;
209709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafonimport android.util.Log;
219709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafonimport java.util.regex.Matcher;
229709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafonimport java.util.regex.Pattern;
239709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon
249709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon/** Parses PSS info from dumpsys meminfo */
259709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafonpublic class MemInfoParser implements PerfParser {
269709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon
279709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon    private static final Pattern LINE_PATTERN =
289709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon        Pattern.compile("\\s*(\\d*,*\\d*)K:\\s(\\S*)\\s\\.*");
299709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon    private static final String PSS_BY_PROCESS = "Total PSS by process:";
309709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon    private static final String TAG = "loadtest.MemInfoParser";
319709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon
329709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon    private boolean mPssStarted;
339709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon    private boolean mPssEnded;
349709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon    private final long mStartTimeMillis;
359709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon
369709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon    public MemInfoParser(long startTimeMillis) {
379709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon        mStartTimeMillis = startTimeMillis;
389709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon    }
399709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon
409709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon    @Override
419709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon    @Nullable
429709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon    public String parseLine(String line) {
439709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon        if (mPssEnded) {
449709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon            return null;
459709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon        }
469709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon        if (!mPssStarted) {
479709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon            if (line.contains(PSS_BY_PROCESS)) {
489709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon                mPssStarted = true;
499709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon            }
509709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon            return null;
519709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon        }
529709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon        if (line.isEmpty()) {
539709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon            mPssEnded = true;
549709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon            return null;
559709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon        }
569709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon        Matcher lineMatcher = LINE_PATTERN.matcher(line);
579709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon        if (lineMatcher.find() && lineMatcher.group(1) != null && lineMatcher.group(2) != null) {
589709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon            if (lineMatcher.group(2).equals("statsd")) {
599709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon                long timeDeltaMillis = SystemClock.elapsedRealtime() - mStartTimeMillis;
609709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon                return timeDeltaMillis + "," + convertToPss(lineMatcher.group(1));
619709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon            }
629709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon        }
639709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon        return null;
649709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon    }
659709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon
669709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon    private String convertToPss(String input) {
679709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon        return input.replace(",", "");
689709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon    }
699709fa26f1e3f713e0558c5cce71c28f208afbe9Stefan Lafon}
70