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

Commit 431d2321 authored by Tomasz Mikolajewski's avatar Tomasz Mikolajewski Committed by Android (Google) Code Review
Browse files

Merge "Add basic jank tests for DocumentsUI." into nyc-dev

parents 362b3156 811777ec
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) \
    ../tests/src/com/android/documentsui/StubProvider.java

LOCAL_JAVA_LIBRARIES := android-support-v4 android.test.runner
LOCAL_STATIC_JAVA_LIBRARIES := mockito-target ub-uiautomator
LOCAL_STATIC_JAVA_LIBRARIES := mockito-target ub-uiautomator ub-janktesthelper

LOCAL_PACKAGE_NAME := DocumentsUIPerfTests
LOCAL_INSTRUMENTATION_FOR := DocumentsUI
+90 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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 com.android.documentsui;

import static com.android.documentsui.StressProvider.DEFAULT_AUTHORITY;
import static com.android.documentsui.StressProvider.STRESS_ROOT_0_ID;
import static com.android.documentsui.StressProvider.STRESS_ROOT_2_ID;

import android.app.Activity;
import android.os.RemoteException;
import android.test.suitebuilder.annotation.LargeTest;

import android.content.Intent;
import android.content.Context;
import android.support.test.jank.JankTest;
import android.support.test.jank.JankTestBase;
import android.support.test.uiautomator.UiDevice;
import android.support.test.jank.GfxMonitor;
import android.support.test.uiautomator.UiScrollable;
import android.util.Log;

import com.android.documentsui.FilesActivity;
import com.android.documentsui.bots.RootsListBot;
import com.android.documentsui.bots.DirectoryListBot;

@LargeTest
public class FilesJankPerfTest extends JankTestBase {
    private static final String DOCUMENTSUI_PACKAGE = "com.android.documentsui";
    private static final int MAX_FLINGS = 10;
    private static final int BOT_TIMEOUT = 5000;

    private RootsListBot mRootsListBot;
    private DirectoryListBot mDirListBot;
    private Activity mActivity = null;

    public void setUpInLoop() {
        final UiDevice device = UiDevice.getInstance(getInstrumentation());
        final Context context = getInstrumentation().getTargetContext();
        mRootsListBot = new RootsListBot(device, context, BOT_TIMEOUT);
        mDirListBot = new DirectoryListBot(device, context, BOT_TIMEOUT);

        final Intent intent = new Intent(context, FilesActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        mActivity = getInstrumentation().startActivitySync(intent);
    }

    public void tearDownInLoop() {
        if (mActivity != null) {
            mActivity.finish();
            mActivity = null;
        }
    }

    public void setupAndOpenInLoop() throws Exception {
        setUpInLoop();
        openRoot();
    }

    public void openRoot() throws Exception {
        mRootsListBot.openRoot(STRESS_ROOT_2_ID);
    }

    @JankTest(expectedFrames=0, beforeLoop="setUpInLoop", afterLoop="tearDownInLoop")
    @GfxMonitor(processName=DOCUMENTSUI_PACKAGE)
    public void testOpenRootJankPerformance() throws Exception {
        openRoot();
        getInstrumentation().waitForIdleSync();
    }

    @JankTest(expectedFrames=0, beforeLoop="setupAndOpenInLoop", afterLoop="tearDownInLoop")
    @GfxMonitor(processName=DOCUMENTSUI_PACKAGE)
    public void testFlingJankPerformance() throws Exception {
        new UiScrollable(mDirListBot.findDocumentsList().getSelector()).flingToEnd(MAX_FLINGS);
        getInstrumentation().waitForIdleSync();
    }
}
+126 −33
Original line number Diff line number Diff line
@@ -32,7 +32,9 @@ import android.provider.DocumentsProvider;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
@@ -46,11 +48,21 @@ public class StressProvider extends DocumentsProvider {
    // Empty root.
    public static final String STRESS_ROOT_0_ID = "STRESS_ROOT_0";

    // Root with thousands of items.
    // Root with thousands of directories.
    public static final String STRESS_ROOT_1_ID = "STRESS_ROOT_1";

    // Root with hundreds of files.
    public static final String STRESS_ROOT_2_ID = "STRESS_ROOT_2";

    private static final String STRESS_ROOT_0_DOC_ID = "STRESS_ROOT_0_DOC";
    private static final String STRESS_ROOT_1_DOC_ID = "STRESS_ROOT_1_DOC";
    private static final String STRESS_ROOT_2_DOC_ID = "STRESS_ROOT_2_DOC";

    private static final int STRESS_ROOT_1_ITEMS = 10000;
    private static final int STRESS_ROOT_2_ITEMS = 300;

    private static final String MIME_TYPE_IMAGE = "image/jpeg";
    private static final long REFERENCE_TIMESTAMP = 1459159369359L;

    private static final String[] DEFAULT_ROOT_PROJECTION = new String[] {
            Root.COLUMN_ROOT_ID, Root.COLUMN_FLAGS, Root.COLUMN_TITLE, Root.COLUMN_DOCUMENT_ID,
@@ -62,7 +74,12 @@ public class StressProvider extends DocumentsProvider {
    };

    private String mAuthority = DEFAULT_AUTHORITY;
    private ArrayList<String> mIds = new ArrayList<>();

    // Map from a root document id to children document ids.
    private Map<String, ArrayList<StubDocument>> mChildDocuments = new HashMap<>();

    private Map<String, StubDocument> mDocuments = new HashMap<>();
    private Map<String, StubRoot> mRoots = new HashMap<>();

    @Override
    public void attachInfo(Context context, ProviderInfo info) {
@@ -72,20 +89,41 @@ public class StressProvider extends DocumentsProvider {

    @Override
    public boolean onCreate() {
        mIds = new ArrayList();
        for (int i = 0; i < 10000; i++) {
            mIds.add(createRandomId(i));
        StubDocument document;

        ArrayList<StubDocument> children = new ArrayList<StubDocument>();
        mChildDocuments.put(STRESS_ROOT_1_DOC_ID, children);
        for (int i = 0; i < STRESS_ROOT_1_ITEMS; i++) {
            document = StubDocument.createDirectory(i);
            mDocuments.put(document.id, document);
            children.add(document);
        }

        children = new ArrayList<StubDocument>();
        mChildDocuments.put(STRESS_ROOT_2_DOC_ID, children);
        for (int i = 0; i < STRESS_ROOT_2_ITEMS; i++) {
            document = StubDocument.createFile(STRESS_ROOT_1_ITEMS + i);
            mDocuments.put(document.id, document);
            children.add(document);
        }
        mIds.add(STRESS_ROOT_0_DOC_ID);
        mIds.add(STRESS_ROOT_1_DOC_ID);

        mRoots.put(STRESS_ROOT_0_ID, new StubRoot(STRESS_ROOT_0_ID, STRESS_ROOT_0_DOC_ID));
        mRoots.put(STRESS_ROOT_1_ID, new StubRoot(STRESS_ROOT_1_ID, STRESS_ROOT_1_DOC_ID));
        mRoots.put(STRESS_ROOT_2_ID, new StubRoot(STRESS_ROOT_2_ID, STRESS_ROOT_2_DOC_ID));

        mDocuments.put(STRESS_ROOT_0_DOC_ID, StubDocument.createDirectory(STRESS_ROOT_0_DOC_ID));
        mDocuments.put(STRESS_ROOT_1_DOC_ID, StubDocument.createDirectory(STRESS_ROOT_1_DOC_ID));
        mDocuments.put(STRESS_ROOT_2_DOC_ID, StubDocument.createDirectory(STRESS_ROOT_2_DOC_ID));

        return true;
    }

    @Override
    public Cursor queryRoots(String[] projection) throws FileNotFoundException {
        final MatrixCursor result = new MatrixCursor(DEFAULT_ROOT_PROJECTION);
        includeRoot(result, STRESS_ROOT_0_ID, STRESS_ROOT_0_DOC_ID);
        includeRoot(result, STRESS_ROOT_1_ID, STRESS_ROOT_1_DOC_ID);
        for (StubRoot root : mRoots.values()) {
            includeRoot(result, root);
        }
        return result;
    }

@@ -93,51 +131,84 @@ public class StressProvider extends DocumentsProvider {
    public Cursor queryDocument(String documentId, String[] projection)
            throws FileNotFoundException {
        final MatrixCursor result = new MatrixCursor(DEFAULT_DOCUMENT_PROJECTION);
        includeDocument(result, documentId);
        final StubDocument document = mDocuments.get(documentId);
        includeDocument(result, document);
        return result;
    }

    @Override
    public Cursor queryChildDocuments(String parentDocumentId, String[] projection, String sortOrder)
    public Cursor queryChildDocuments(String parentDocumentId, String[] projection,
            String sortOrder)
            throws FileNotFoundException {
        final MatrixCursor result = new MatrixCursor(DEFAULT_DOCUMENT_PROJECTION);
        if (STRESS_ROOT_1_DOC_ID.equals(parentDocumentId)) {
            for (String id : mIds) {
                includeDocument(result, id);
        final ArrayList<StubDocument> childDocuments = mChildDocuments.get(parentDocumentId);
        if (childDocuments != null) {
            for (StubDocument document : childDocuments) {
                includeDocument(result, document);
            }
        }
        return result;
    }

    @Override
    public ParcelFileDescriptor openDocument(String docId, String mode, CancellationSignal signal)
    public ParcelFileDescriptor openDocument(String docId, String mode,
            CancellationSignal signal)
            throws FileNotFoundException {
        throw new UnsupportedOperationException();
    }

    private void includeRoot(MatrixCursor result, String rootId, String docId) {
    private void includeRoot(MatrixCursor result, StubRoot root) {
        final RowBuilder row = result.newRow();
        row.add(Root.COLUMN_ROOT_ID, rootId);
        row.add(Root.COLUMN_ROOT_ID, root.id);
        row.add(Root.COLUMN_FLAGS, 0);
        row.add(Root.COLUMN_TITLE, rootId);
        row.add(Root.COLUMN_DOCUMENT_ID, docId);
        row.add(Root.COLUMN_TITLE, root.id);
        row.add(Root.COLUMN_DOCUMENT_ID, root.documentId);
    }

    private void includeDocument(MatrixCursor result, String id) {
    private void includeDocument(MatrixCursor result, StubDocument document) {
        final RowBuilder row = result.newRow();
        row.add(Document.COLUMN_DOCUMENT_ID, id);
        row.add(Document.COLUMN_DISPLAY_NAME, id);
        row.add(Document.COLUMN_SIZE, 0);
        row.add(Document.COLUMN_MIME_TYPE, DocumentsContract.Document.MIME_TYPE_DIR);
        row.add(Document.COLUMN_DOCUMENT_ID, document.id);
        row.add(Document.COLUMN_DISPLAY_NAME, document.id);
        row.add(Document.COLUMN_SIZE, document.size);
        row.add(Document.COLUMN_MIME_TYPE, document.mimeType);
        row.add(Document.COLUMN_FLAGS, 0);
        row.add(Document.COLUMN_LAST_MODIFIED, null);
        row.add(Document.COLUMN_LAST_MODIFIED, document.lastModified);
    }

    private static String getDocumentIdForFile(File file) {
    private static String getStubDocumentIdForFile(File file) {
        return file.getAbsolutePath();
    }

    private String createRandomId(int index) {
    private static class StubDocument {
        final String mimeType;
        final String id;
        final int size;
        final long lastModified;

        private StubDocument(String mimeType, String id, int size, long lastModified) {
            this.mimeType = mimeType;
            this.id = id;
            this.size = size;
            this.lastModified = lastModified;
        }

        public static StubDocument createDirectory(int index) {
            return new StubDocument(
                    DocumentsContract.Document.MIME_TYPE_DIR, createRandomId(index), 0,
                    createRandomTime(index));
        }

        public static StubDocument createDirectory(String id) {
            return new StubDocument(DocumentsContract.Document.MIME_TYPE_DIR, id, 0, 0);
        }

        public static StubDocument createFile(int index) {
            return new StubDocument(
                    MIME_TYPE_IMAGE, createRandomId(index), createRandomSize(index),
                    createRandomTime(index));
        }

        private static String createRandomId(int index) {
            final Random random = new Random(index);
            final StringBuilder builder = new StringBuilder();
            for (int i = 0; i < 20; i++) {
@@ -146,4 +217,26 @@ public class StressProvider extends DocumentsProvider {
            builder.append(index);  // Append a number to guarantee uniqueness.
            return builder.toString();
        }

        private static int createRandomSize(int index) {
            final Random random = new Random(index);
            return random.nextInt(1024 * 1024 * 100);  // Up to 100 MB.
        }

        private static long createRandomTime(int index) {
            final Random random = new Random(index);
            // Up to 30 days backwards from REFERENCE_TIMESTAMP.
            return REFERENCE_TIMESTAMP - random.nextLong() % 1000L * 60 * 60 * 24 * 30;
        }
    }

    private static class StubRoot {
        final String id;
        final String documentId;

        public StubRoot(String id, String documentId) {
            this.id = id;
            this.documentId = documentId;
        }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -167,7 +167,7 @@ public class DirectoryListBot extends BaseBot {
        return true;
    }

    private UiObject findDocumentsList() {
    public UiObject findDocumentsList() {
        return findObject(
                "com.android.documentsui:id/container_directory",
                DIR_LIST_ID);