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

Commit 84121313 authored by Jing Ji's avatar Jing Ji
Browse files

Add performance test for OomAdjuster

Bug: 140254153
Test: atest -c ActivityManagerPerfTests:OomAdjPerfTest#testOomAdj
Change-Id: Id12667c71300e6fe4dc063c83807834bbdb5e62a
parent 81826ce7
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -95,7 +95,7 @@ public class InternalWindowOperationPerfTest extends WindowManagerPerfTestBase {

        mTraceMarkParser.forAllSlices((key, slices) -> {
            for (TraceMarkSlice slice : slices) {
                state.addExtraResult(key, (long) (slice.getDurarionInSeconds() * NANOS_PER_S));
                state.addExtraResult(key, (long) (slice.getDurationInSeconds() * NANOS_PER_S));
            }
        });

+22 −2
Original line number Diff line number Diff line
@@ -23,11 +23,15 @@ import android.os.Bundle;
import android.util.ArrayMap;
import android.util.Log;

import com.android.internal.util.ArrayUtils;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
@@ -140,6 +144,8 @@ public final class ManualBenchmarkState {
    /** @see #addExtraResult(String, long) */
    private ArrayMap<String, ArrayList<Long>> mExtraResults;

    private final List<Long> mTmpDurations = Arrays.asList(0L);

    // Statistics. These values will be filled when the benchmark has finished.
    // The computation needs double precision, but long int is fine for final reporting.
    private Stats mStats;
@@ -188,14 +194,25 @@ public final class ManualBenchmarkState {
        if (duration < 0) {
            throw new RuntimeException("duration is negative: " + duration);
        }
        mTmpDurations.set(0, duration);
        return keepRunning(mTmpDurations);
    }

    /**
     * Similar to the {@link #keepRunning(long)} but accepts a list of durations
     */
    public boolean keepRunning(List<Long> durations) {
        switch (mState) {
            case NOT_STARTED:
                mState = WARMUP;
                mWarmupStartTime = System.nanoTime();
                return true;
            case WARMUP: {
                if (ArrayUtils.isEmpty(durations)) {
                    return true;
                }
                final long timeSinceStartingWarmup = System.nanoTime() - mWarmupStartTime;
                ++mWarmupIterations;
                mWarmupIterations += durations.size();
                if (mWarmupIterations >= WARMUP_MIN_ITERATIONS
                        && timeSinceStartingWarmup >= mWarmupDurationNs) {
                    beginBenchmark(timeSinceStartingWarmup, mWarmupIterations);
@@ -203,7 +220,10 @@ public final class ManualBenchmarkState {
                return true;
            }
            case RUNNING: {
                mResults.add(duration);
                if (ArrayUtils.isEmpty(durations)) {
                    return true;
                }
                mResults.addAll(durations);
                final boolean keepRunning = mResults.size() < mMaxIterations;
                if (!keepRunning) {
                    mStats = new Stats(mResults);
+41 −5
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@ public class TraceMarkParser {

    private final Predicate<TraceMarkLine> mTraceLineFilter;

    private static final long MICROS_PER_SECOND = 1000L * 1000L;

    public TraceMarkParser(Predicate<TraceMarkLine> traceLineFilter) {
        mTraceLineFilter = traceLineFilter;
    }
@@ -116,13 +118,19 @@ public class TraceMarkParser {
        }
    }

    public void reset() {
        mSlicesMap.clear();
        mDepthMap.clear();
        mPendingStarts.clear();
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();
        forAllSlices((key, slices) -> {
            double totalMs = 0;
            for (TraceMarkSlice s : slices) {
                totalMs += s.getDurarionInSeconds() * 1000;
                totalMs += s.getDurationInSeconds() * 1000;
            }
            sb.append(key).append(" count=").append(slices.size()).append(" avg=")
                    .append(totalMs / slices.size()).append("ms\n");
@@ -134,6 +142,10 @@ public class TraceMarkParser {
        return sb.toString();
    }

    static double microsecondToSeconds(long ms) {
        return (ms * 1.0d) / MICROS_PER_SECOND;
    }

    public static class TraceMarkSlice {
        public final TraceMarkLine begin;
        public final TraceMarkLine end;
@@ -143,7 +155,11 @@ public class TraceMarkParser {
            this.end = end;
        }

        public double getDurarionInSeconds() {
        public double getDurationInSeconds() {
            return microsecondToSeconds(end.timestamp - begin.timestamp);
        }

        public long getDurationInMicroseconds() {
            return end.timestamp - begin.timestamp;
        }
    }
@@ -164,7 +180,7 @@ public class TraceMarkParser {
        static final char SYNC_END = 'E';

        public final String taskPid;
        public final double timestamp;
        public final long timestamp; // in microseconds
        public final String name;
        public final boolean isAsync;
        public final boolean isBegin;
@@ -179,7 +195,7 @@ public class TraceMarkParser {
            if (timeBegin < 0) {
                throw new IllegalArgumentException("Timestamp start not found");
            }
            timestamp = Double.parseDouble(rawLine.substring(timeBegin, timeEnd));
            timestamp = parseMicroseconds(rawLine.substring(timeBegin, timeEnd));
            isAsync = type == ASYNC_START || type == ASYNC_FINISH;
            isBegin = type == ASYNC_START || type == SYNC_BEGIN;

@@ -223,9 +239,29 @@ public class TraceMarkParser {
            return null;
        }

        /**
         * Parse the timestamp from atrace output, the format will be like:
         * 84962.920719  where the decimal part will be always exactly 6 digits.
         * ^^^^^ ^^^^^^
         * |     |
         * sec   microsec
         */
        static long parseMicroseconds(String line) {
            int end = line.length();
            long t = 0;
            for (int i = 0; i < end; i++) {
                char c = line.charAt(i);
                if (c >= '0' && c <= '9') {
                    t = t * 10 + (c - '0');
                }
            }
            return t;
        }

        @Override
        public String toString() {
            return "TraceMarkLine{pid=" + taskPid + " time=" + timestamp + " name=" + name
            return "TraceMarkLine{pid=" + taskPid + " time="
                    + microsecondToSeconds(timestamp) + " name=" + name
                    + " async=" + isAsync + " begin=" + isBegin + "}";
        }
    }
+68 −0
Original line number Diff line number Diff line
// Copyright (C) 2019 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.

android_test_helper_app {
    name: "ActivityManagerPerfTestsStubApp1",
    static_libs: ["ActivityManagerPerfTestsUtils"],
    srcs: [
        "src/**/*.java",
    ],
    resource_dirs: [
        "app1/res",
        "res",
    ],
    platform_apis: true,
    certificate: "platform",
    aaptflags: [
        "--rename-manifest-package com.android.stubs.am1",
        "--auto-add-overlay",
    ],
}

android_test_helper_app {
    name: "ActivityManagerPerfTestsStubApp2",
    static_libs: ["ActivityManagerPerfTestsUtils"],
    srcs: [
        "src/**/*.java",
    ],
    resource_dirs: [
        "app2/res",
        "res",
    ],
    platform_apis: true,
    certificate: "platform",
    aaptflags: [
        "--rename-manifest-package com.android.stubs.am2",
        "--auto-add-overlay",
    ],
}

android_test_helper_app {
    name: "ActivityManagerPerfTestsStubApp3",
    static_libs: ["ActivityManagerPerfTestsUtils"],
    srcs: [
        "src/**/*.java",
    ],
    resource_dirs: [
        "app3/res",
        "res",
    ],
    platform_apis: true,
    certificate: "platform",
    aaptflags: [
        "--rename-manifest-package com.android.stubs.am3",
        "--auto-add-overlay",
    ],
}
+54 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
 * Copyright (C) 2019 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.
 -->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.android.stubs.am">

    <uses-permission android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/>
    <application android:label="Android TestCase" >
        <provider
                android:authorities="@string/authority"
                android:name=".TestContentProvider"
                android:exported="true" />
        <receiver
                android:name=".TestBroadcastReceiver"
                android:exported="true">
            <intent-filter>
                <action android:name="com.android.stubs.am.ACTION_BROADCAST_TEST" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>
        <service
                android:name=".InitService"
                android:exported="true" />
        <service
                android:name=".TestService"
                android:exported="true" />
        <activity
                android:name=".TestActivity"
                android:excludeFromRecents="true"
                android:turnScreenOn="true"
                android:launchMode="singleTask">
            <intent-filter>
                <action android:name="com.android.stubs.am.ACTION_START_TEST_ACTIVITY" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>

</manifest>
Loading