blob: 1bc802a00ec6303314ec6c9cc91b33abb58f29e2 [file] [log] [blame]
Tomasz Mikolajewskiae6d6b42016-02-24 12:53:44 +09001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.documentsui;
18
19import android.content.Context;
20import android.content.pm.ProviderInfo;
21import android.database.Cursor;
22import android.database.MatrixCursor.RowBuilder;
23import android.database.MatrixCursor;
24import android.os.CancellationSignal;
25import android.os.FileUtils;
26import android.os.ParcelFileDescriptor;
27import android.provider.DocumentsContract.Document;
28import android.provider.DocumentsContract.Root;
29import android.provider.DocumentsContract;
30import android.provider.DocumentsProvider;
31
32import java.io.File;
33import java.io.FileNotFoundException;
34import java.util.ArrayList;
35import java.util.List;
36import java.util.Random;
37
38/**
39 * Provider with thousands of files for testing loading time of directories in DocumentsUI.
40 * It doesn't support any file operations.
41 */
42public class StressProvider extends DocumentsProvider {
43
44 public static final String DEFAULT_AUTHORITY = "com.android.documentsui.stressprovider";
45
46 // Empty root.
47 public static final String STRESS_ROOT_0_ID = "STRESS_ROOT_0";
48
49 // Root with thousands of items.
50 public static final String STRESS_ROOT_1_ID = "STRESS_ROOT_1";
51
52 private static final String STRESS_ROOT_0_DOC_ID = "STRESS_ROOT_0_DOC";
53 private static final String STRESS_ROOT_1_DOC_ID = "STRESS_ROOT_1_DOC";
54
55 private static final String[] DEFAULT_ROOT_PROJECTION = new String[] {
56 Root.COLUMN_ROOT_ID, Root.COLUMN_FLAGS, Root.COLUMN_TITLE, Root.COLUMN_DOCUMENT_ID,
57 Root.COLUMN_AVAILABLE_BYTES
58 };
59 private static final String[] DEFAULT_DOCUMENT_PROJECTION = new String[] {
60 Document.COLUMN_DOCUMENT_ID, Document.COLUMN_MIME_TYPE, Document.COLUMN_DISPLAY_NAME,
61 Document.COLUMN_LAST_MODIFIED, Document.COLUMN_FLAGS, Document.COLUMN_SIZE,
62 };
63
64 private String mAuthority = DEFAULT_AUTHORITY;
65 private ArrayList<String> mIds = new ArrayList<>();
66
67 @Override
68 public void attachInfo(Context context, ProviderInfo info) {
69 mAuthority = info.authority;
70 super.attachInfo(context, info);
71 }
72
73 @Override
74 public boolean onCreate() {
75 mIds = new ArrayList();
76 for (int i = 0; i < 10000; i++) {
77 mIds.add(createRandomId(i));
78 }
79 mIds.add(STRESS_ROOT_0_DOC_ID);
80 mIds.add(STRESS_ROOT_1_DOC_ID);
81 return true;
82 }
83
84 @Override
85 public Cursor queryRoots(String[] projection) throws FileNotFoundException {
86 final MatrixCursor result = new MatrixCursor(DEFAULT_ROOT_PROJECTION);
87 includeRoot(result, STRESS_ROOT_0_ID, STRESS_ROOT_0_DOC_ID);
88 includeRoot(result, STRESS_ROOT_1_ID, STRESS_ROOT_1_DOC_ID);
89 return result;
90 }
91
92 @Override
93 public Cursor queryDocument(String documentId, String[] projection)
94 throws FileNotFoundException {
95 final MatrixCursor result = new MatrixCursor(DEFAULT_DOCUMENT_PROJECTION);
96 includeDocument(result, documentId);
97 return result;
98 }
99
100 @Override
101 public Cursor queryChildDocuments(String parentDocumentId, String[] projection, String sortOrder)
102 throws FileNotFoundException {
103 final MatrixCursor result = new MatrixCursor(DEFAULT_DOCUMENT_PROJECTION);
104 if (STRESS_ROOT_1_DOC_ID.equals(parentDocumentId)) {
105 for (String id : mIds) {
106 includeDocument(result, id);
107 }
108 }
109 return result;
110 }
111
112 @Override
113 public ParcelFileDescriptor openDocument(String docId, String mode, CancellationSignal signal)
114 throws FileNotFoundException {
115 throw new UnsupportedOperationException();
116 }
117
118 private void includeRoot(MatrixCursor result, String rootId, String docId) {
119 final RowBuilder row = result.newRow();
120 row.add(Root.COLUMN_ROOT_ID, rootId);
121 row.add(Root.COLUMN_FLAGS, 0);
122 row.add(Root.COLUMN_TITLE, rootId);
123 row.add(Root.COLUMN_DOCUMENT_ID, docId);
124 }
125
126 private void includeDocument(MatrixCursor result, String id) {
127 final RowBuilder row = result.newRow();
128 row.add(Document.COLUMN_DOCUMENT_ID, id);
129 row.add(Document.COLUMN_DISPLAY_NAME, id);
130 row.add(Document.COLUMN_SIZE, 0);
131 row.add(Document.COLUMN_MIME_TYPE, DocumentsContract.Document.MIME_TYPE_DIR);
132 row.add(Document.COLUMN_FLAGS, 0);
133 row.add(Document.COLUMN_LAST_MODIFIED, null);
134 }
135
136 private static String getDocumentIdForFile(File file) {
137 return file.getAbsolutePath();
138 }
139
140 private String createRandomId(int index) {
141 final Random random = new Random(index);
142 final StringBuilder builder = new StringBuilder();
143 for (int i = 0; i < 20; i++) {
144 builder.append((char) (random.nextInt(96) + 32));
145 }
146 builder.append(index); // Append a number to guarantee uniqueness.
147 return builder.toString();
148 }
149}