--- /dev/null
+/*
+ * 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();
+ }
+}
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;
/**
// 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,
};
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) {
@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;
}
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) {
- final Random random = new Random(index);
- final StringBuilder builder = new StringBuilder();
- for (int i = 0; i < 20; i++) {
- builder.append((char) (random.nextInt(96) + 32));
+ 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++) {
+ builder.append((char) (random.nextInt(96) + 32));
+ }
+ 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;
}
- builder.append(index); // Append a number to guarantee uniqueness.
- return builder.toString();
}
}