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

Commit cb1f2043 authored by Yury Khmel's avatar Yury Khmel Committed by Android (Google) Code Review
Browse files

Merge "Add initial GamePerformance test."

parents c27024d9 017a9782
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
# Copyright (C) 2018 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.

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

# Don't include this package in any target
LOCAL_MODULE_TAGS := tests

LOCAL_DEX_PREOPT := false

LOCAL_PROGUARD_ENABLED := disabled

LOCAL_SRC_FILES := $(call all-java-files-under, src)

LOCAL_STATIC_JAVA_LIBRARIES := android-support-test

LOCAL_JAVA_LIBRARIES := android.test.base android.test.runner

LOCAL_PACKAGE_NAME := GamePerformance

LOCAL_PRIVATE_PLATFORM_APIS := true

LOCAL_CERTIFICATE := platform


include $(BUILD_PACKAGE)
+40 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
 * Copyright (C) 2018 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="android.gameperformance">
    <uses-sdk android:minSdkVersion="25"/>
    <uses-feature android:glEsVersion="0x00020000" android:required="true" />

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <application android:theme="@style/noeffects">
        <uses-library android:name="android.test.runner" />
        <activity android:name="android.gameperformance.GamePerformanceActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <uses-library android:name="android.test.runner" />
    </application>

    <!--  self-instrumenting test package. -->
    <instrumentation android:name="android.test.InstrumentationTestRunner"
                     android:targetPackage="android.gameperformance">
    </instrumentation>
</manifest>
+25 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
 * Copyright (C) 2018 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.
 -->
<resources>
    <style name="noeffects" parent="@android:style/Theme.Holo.NoActionBar.Fullscreen">
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowFullscreen">true</item>
        <item name="android:fadingEdge">none</item>
        <item name="android:windowContentTransitions">false</item>
        <item name="android:windowAnimationStyle">@null</item>
    </style>
</resources>
+94 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.gameperformance;

import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;

import android.app.Instrumentation;
import android.os.AsyncTask;
import android.os.ParcelFileDescriptor;
import android.util.Log;

/**
 * Helper that runs atrace command for required duration and category. Results are read from
 * the output of atrace and serialized to the provided file. We cannot use direct atrace to
 * file because atrace is executed in UI automator context and analysis is done in test context.
 * In last case output file is not accessible from the both contexts.
 */
public class ATraceRunner extends AsyncTask<Void, Integer, Boolean>{
    private final static String TAG = "ATraceRunner";

    // Report that atrace is done.
    public interface Delegate {
        public void onProcessed(boolean success);
    }

    private final Instrumentation mInstrumentation;
    private final String mOutput;
    private final int mTimeInSeconds;
    private final String mCategory;
    private final Delegate mDelegate;

    public ATraceRunner(Instrumentation instrumentation,
                        String output,
                        int timeInSeconds,
                        String category,
                        Delegate delegate) {
        mInstrumentation = instrumentation;
        mOutput = output;
        mTimeInSeconds = timeInSeconds;
        mCategory = category;
        mDelegate = delegate;
    }

    @Override
    protected Boolean doInBackground(Void... params) {
        BufferedReader bufferedReader = null;
        FileWriter writer = null;
        try {
            // Run the command.
            final String cmd = "atrace -t " + mTimeInSeconds + " " + mCategory;
            Log.i(TAG, "Running atrace... " + cmd);
            writer = new FileWriter(mOutput);
            final ParcelFileDescriptor fd =
                    mInstrumentation.getUiAutomation().executeShellCommand(cmd);
            bufferedReader = new BufferedReader(
                    new InputStreamReader(new ParcelFileDescriptor.AutoCloseInputStream(fd)));
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                writer.write(line);
                writer.write("\n");
            }
            Log.i(TAG, "Running atrace... DONE");
            return true;
        } catch (IOException e) {
            Log.i(TAG, "atrace failed", e);
            return false;
        } finally {
            Utils.closeQuietly(bufferedReader);
            Utils.closeQuietly(writer);
        }
    }

    @Override
    protected void onPostExecute(Boolean result) {
        mDelegate.onProcessed(result);
    }

}
+91 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.gameperformance;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;

public class CustomOpenGLView extends GLSurfaceView {
    private Random mRandom;
    private List<Long> mFrameTimes;

    public CustomOpenGLView(Context context) {
        super(context);

        mRandom = new Random();
        mFrameTimes = new ArrayList<Long>();

        setEGLContextClientVersion(2);

        setRenderer(new GLSurfaceView.Renderer() {
            @Override
            public void onSurfaceCreated(GL10 gl, EGLConfig config) {
                GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
                gl.glClearDepthf(1.0f);
                gl.glEnable(GL10.GL_DEPTH_TEST);
                gl.glDepthFunc(GL10.GL_LEQUAL);

                gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
                          GL10.GL_NICEST);            }

            @Override
            public void onSurfaceChanged(GL10 gl, int width, int height) {
                GLES20.glViewport(0, 0, width, height);
            }

            @Override
            public void onDrawFrame(GL10 gl) {
                GLES20.glClearColor(
                        mRandom.nextFloat(), mRandom.nextFloat(), mRandom.nextFloat(), 1.0f);
                gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
                synchronized (mFrameTimes) {
                    mFrameTimes.add(System.currentTimeMillis());
                }
            }
        });
        setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
    }

    /**
     * Resets frame times in order to calculate fps for different test pass.
     */
    public void resetFrameTimes() {
        synchronized (mFrameTimes) {
            mFrameTimes.clear();
        }
    }

    /**
     * Returns current fps based on collected frame times.
     */
    public double getFps() {
        synchronized (mFrameTimes) {
            if (mFrameTimes.size() < 2) {
                return 0.0f;
            }
            return 1000.0 * mFrameTimes.size() /
                    (mFrameTimes.get(mFrameTimes.size() - 1) - mFrameTimes.get(0));
        }
    }
}
Loading