1 /* 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 17 package com.android.documentsui; 18 19 import android.app.Activity; 20 import android.app.ActivityManager; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.pm.PackageManager; 24 import android.content.pm.ResolveInfo; 25 import android.os.Bundle; 26 import android.provider.DocumentsContract; 27 import android.support.test.uiautomator.UiDevice; 28 import android.test.InstrumentationTestCase; 29 import android.test.suitebuilder.annotation.LargeTest; 30 31 import androidx.test.InstrumentationRegistry; 32 import androidx.test.runner.AndroidJUnit4; 33 34 import org.junit.BeforeClass; 35 import org.junit.Test; 36 import org.junit.runner.RunWith; 37 38 import java.util.Arrays; 39 import java.util.List; 40 import java.util.concurrent.CountDownLatch; 41 42 @RunWith(AndroidJUnit4.class) 43 public class FilesAppPerfTest { 44 45 // Keys used to report metrics to APCT. 46 private static final String KEY_FILES_COLD_START_PERFORMANCE_MEDIAN = 47 "files-cold-start-performance-median"; 48 private static final String KEY_FILES_WARM_START_PERFORMANCE_MEDIAN = 49 "files-warm-start-performance-median"; 50 51 private static final String TARGET_PACKAGE = "com.android.documentsui"; 52 53 private static final int NUM_MEASUREMENTS = 10; 54 55 private LauncherActivity mActivity; 56 private static UiDevice mDevice; 57 58 @BeforeClass setUp()59 public static void setUp() { 60 mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); 61 } 62 63 @Test testFilesColdStartPerformance()64 public void testFilesColdStartPerformance() throws Exception { 65 runFilesStartPerformanceTest(true); 66 } 67 68 @Test testFilesWarmStartPerformance()69 public void testFilesWarmStartPerformance() throws Exception { 70 runFilesStartPerformanceTest(false); 71 } 72 runFilesStartPerformanceTest(boolean cold)73 public void runFilesStartPerformanceTest(boolean cold) throws Exception { 74 long[] measurements = new long[NUM_MEASUREMENTS]; 75 for (int i = 0; i < NUM_MEASUREMENTS; i++) { 76 if (cold) { 77 // Kill all providers, as well as DocumentsUI to measure a cold start. 78 killProviders(); 79 mDevice.executeShellCommand("am force-stop " + TARGET_PACKAGE); 80 } 81 mDevice.waitForIdle(); 82 83 LauncherActivity.testCaseLatch = new CountDownLatch(1); 84 mActivity = launchActivity( 85 InstrumentationRegistry.getInstrumentation().getTargetContext() 86 .getPackageName(), 87 LauncherActivity.class, null); 88 LauncherActivity.testCaseLatch.await(); 89 measurements[i] = LauncherActivity.measurement; 90 } 91 92 reportMetrics(cold ? KEY_FILES_COLD_START_PERFORMANCE_MEDIAN 93 : KEY_FILES_WARM_START_PERFORMANCE_MEDIAN, measurements); 94 } 95 reportMetrics(String key, long[] measurements)96 private void reportMetrics(String key, long[] measurements) { 97 final Bundle status = new Bundle(); 98 Arrays.sort(measurements); 99 final long median = measurements[NUM_MEASUREMENTS / 2 - 1]; 100 status.putDouble(key, median); 101 102 InstrumentationRegistry.getInstrumentation().sendStatus(Activity.RESULT_OK, status); 103 } 104 killProviders()105 private void killProviders() throws Exception { 106 final Context context = InstrumentationRegistry.getInstrumentation().getContext(); 107 final PackageManager pm = context.getPackageManager(); 108 final ActivityManager am = (ActivityManager) context.getSystemService( 109 Context.ACTIVITY_SERVICE); 110 final Intent intent = new Intent(DocumentsContract.PROVIDER_INTERFACE); 111 final List<ResolveInfo> providers = pm.queryIntentContentProviders(intent, 0); 112 for (ResolveInfo info : providers) { 113 final String packageName = info.providerInfo.packageName; 114 am.killBackgroundProcesses(packageName); 115 } 116 } 117 launchActivity( String pkg, Class<T> activityCls, Bundle extras)118 private final <T extends Activity> T launchActivity( 119 String pkg, 120 Class<T> activityCls, 121 Bundle extras) { 122 Intent intent = new Intent(Intent.ACTION_MAIN); 123 if (extras != null) { 124 intent.putExtras(extras); 125 } 126 return launchActivityWithIntent(pkg, activityCls, intent); 127 } 128 launchActivityWithIntent( String pkg, Class<T> activityCls, Intent intent)129 private final <T extends Activity> T launchActivityWithIntent( 130 String pkg, 131 Class<T> activityCls, 132 Intent intent) { 133 intent.setClassName(pkg, activityCls.getName()); 134 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 135 T activity = (T) InstrumentationRegistry.getInstrumentation().startActivitySync(intent); 136 InstrumentationRegistry.getInstrumentation().waitForIdleSync(); 137 return activity; 138 } 139 } 140