public class

JankMonitorFactory

extends java.lang.Object

implements IMonitorFactory

 java.lang.Object

↳androidx.test.jank.internal.JankMonitorFactory

Gradle dependencies

compile group: 'androidx.test.janktesthelper', name: 'janktesthelper', version: '1.0.1'

  • groupId: androidx.test.janktesthelper
  • artifactId: janktesthelper
  • version: 1.0.1

Artifact androidx.test.janktesthelper:janktesthelper:1.0.1 it located at Google repository (https://maven.google.com/)

Overview

An IMonitorFactory for constructing monitors that detect Jank.

Summary

Constructors
publicJankMonitorFactory(Instrumentation instrumentation)

Default constructor.

Methods
protected InstrumentationgetInstrumentation()

Returns the instance.

public java.util.List<IMonitor>getMonitors(java.lang.reflect.Method testMethod, java.lang.Object testInstance)

protected java.lang.StringresolveGfxMonitorProcessName(java.lang.String methodName, java.lang.Object target)

Call the method with the given methodName to obtain the name of the process that GfxMonitor should watch.

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructors

public JankMonitorFactory(Instrumentation instrumentation)

Default constructor.

Methods

public java.util.List<IMonitor> getMonitors(java.lang.reflect.Method testMethod, java.lang.Object testInstance)

protected java.lang.String resolveGfxMonitorProcessName(java.lang.String methodName, java.lang.Object target)

Call the method with the given methodName to obtain the name of the process that GfxMonitor should watch.

protected Instrumentation getInstrumentation()

Returns the instance.

Source

/*
 * Copyright (C) 2015 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 androidx.test.jank.internal;

import android.app.Instrumentation;
import android.os.Build;
import androidx.test.jank.GfxMonitor;
import androidx.test.jank.GfxFrameStatsMonitor;
import androidx.test.jank.IMonitor;
import androidx.test.jank.IMonitorFactory;
import androidx.test.jank.JankTestBase;
import androidx.test.jank.WindowAnimationFrameStatsMonitor;
import androidx.test.jank.WindowContentFrameStatsMonitor;
import android.util.Log;

import junit.framework.Assert;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

/**
 * An {@link IMonitorFactory} for constructing monitors that detect Jank.
 * @hide
 */
public class JankMonitorFactory implements IMonitorFactory {

    private static String TAG = "JankTestHelper";

    static final int API_LEVEL_ACTUAL = Build.VERSION.SDK_INT
            + ("REL".equals(Build.VERSION.CODENAME) ? 0 : 1);

    private Instrumentation mInstrumentation;

    /**
     * Default constructor.
     */
    public JankMonitorFactory(Instrumentation instrumentation) {
        mInstrumentation = instrumentation;
    }

    /**
     * {@inheritDoc}
     */
    public List<IMonitor> getMonitors(Method testMethod, Object testInstance) {
        List<IMonitor> monitors = new ArrayList<>();

        GfxMonitor gfxMonitorArgs = testMethod.getAnnotation(GfxMonitor.class);
        if (gfxMonitorArgs != null) {
            // GfxMonitor only works on M+. NB: Hard coding value since SDK 22 isn't in prebuilts.
            if (API_LEVEL_ACTUAL <= 22) {
                Log.w(TAG, "Skipping GfxMonitor. Not supported by current platform.");
            } else {
                String process = gfxMonitorArgs.processName();
                if (process.startsWith("#")) {
                    process = resolveGfxMonitorProcessName(process.substring(1), testInstance);
                }
                monitors.add(new GfxMonitorImpl(getInstrumentation(), process));
            }
        }

        GfxFrameStatsMonitor gfxFrameStatsMonitorArgs = testMethod.getAnnotation(
                GfxFrameStatsMonitor.class);
        if (gfxFrameStatsMonitorArgs != null) {
            // GfxMonitor only works on M+. NB: Hard coding value since SDK 22 isn't in prebuilts.
            if (API_LEVEL_ACTUAL <= 22) {
                Log.w(TAG, "Skipping GfxMonitor. Not supported by current platform.");
            } else {
                String process = gfxFrameStatsMonitorArgs.processName();
                if (process.startsWith("#")) {
                    process = resolveGfxMonitorProcessName(process.substring(1), testInstance);
                }
                monitors.add(new GfxFrameStatsMonitorImpl(getInstrumentation(), process));
            }
        }

        WindowAnimationFrameStatsMonitor animationFrameMonitorArgs = testMethod.getAnnotation(
                WindowAnimationFrameStatsMonitor.class);
        if (animationFrameMonitorArgs != null) {
            monitors.add(new WindowAnimationFrameStatsMonitorImpl(getInstrumentation()));
        }

        WindowContentFrameStatsMonitor contentFrameMonitorArgs = testMethod.getAnnotation(
                WindowContentFrameStatsMonitor.class);
        if (contentFrameMonitorArgs != null) {
            monitors.add(new WindowContentFrameStatsMonitorImpl(getInstrumentation()));
        }

        return monitors;
    }

    /**
     * Call the method with the given {@code methodName} to obtain the name of the process that
     * GfxMonitor should watch.
     */
    protected String resolveGfxMonitorProcessName(String methodName, Object target) {
        String processName = null;
        try {
            Method method = target.getClass().getMethod(methodName, (Class[])null);
            processName = (String)method.invoke(target);
        } catch (NoSuchMethodException e) {
            String msg = String.format("Method \"%s\" not found", methodName);
            throw new AssertionError(msg, e);
        } catch (ClassCastException e) {
            String msg = String.format("Method \"%s\" should return a String", methodName);
            throw new AssertionError(msg, e);
        } catch (IllegalAccessException e) {
            // Shouldn't happen. If the method is private, getMethod(..) will throw
            // NoSuchMethodException first. Catching this just to keep the compiler happy.
            String msg = String.format("Method \"%s\" should be public", methodName);
            throw new AssertionError(msg, e);
        } catch (InvocationTargetException e) {
            String msg = String.format("Exception while invoking \"%s\" to obtain process name: %s",
                      methodName, e.getCause() != null ? e.getCause().toString() : e.toString());
            throw new AssertionError(msg, e.getCause() != null ? e.getCause() : e);
        }
        return processName;
    }

    /**
     * Returns the {@link Instrumentation} instance.
     */
    protected Instrumentation getInstrumentation() {
        return mInstrumentation;
    }
}