1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * 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, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17 package com.android.launcher3.tapl; 18 19 import static androidx.test.InstrumentationRegistry.getInstrumentation; 20 import static androidx.test.InstrumentationRegistry.getTargetContext; 21 22 import android.app.Instrumentation; 23 import android.content.ComponentName; 24 import android.content.Context; 25 import android.content.Intent; 26 import android.content.pm.ActivityInfo; 27 import android.content.pm.ResolveInfo; 28 import android.content.res.Resources; 29 import android.os.DropBoxManager; 30 import android.os.SystemClock; 31 import android.util.Log; 32 33 import androidx.test.uiautomator.SearchCondition; 34 import androidx.test.uiautomator.UiDevice; 35 36 import org.junit.Assert; 37 38 import java.util.Date; 39 import java.util.List; 40 41 public class TestHelpers { 42 43 private static final String TAG = "Tapl"; 44 private static Boolean sIsInLauncherProcess; 45 isInLauncherProcess()46 public static boolean isInLauncherProcess() { 47 if (sIsInLauncherProcess == null) { 48 sIsInLauncherProcess = initIsInLauncherProcess(); 49 } 50 return sIsInLauncherProcess; 51 } 52 initIsInLauncherProcess()53 private static boolean initIsInLauncherProcess() { 54 ActivityInfo info = getLauncherInMyProcess(); 55 56 // If we are in the same process, we can instantiate the class name. 57 try { 58 Class launcherClazz = Class.forName("com.android.launcher3.Launcher"); 59 return launcherClazz.isAssignableFrom(Class.forName(info.name)); 60 } catch (Exception e) { 61 return false; 62 } 63 } 64 getHomeIntentInPackage(Context context)65 public static Intent getHomeIntentInPackage(Context context) { 66 return new Intent(Intent.ACTION_MAIN) 67 .addCategory(Intent.CATEGORY_HOME) 68 .setPackage(context.getPackageName()) 69 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 70 } 71 getLauncherInMyProcess()72 public static ActivityInfo getLauncherInMyProcess() { 73 Instrumentation instrumentation = getInstrumentation(); 74 if (instrumentation.getTargetContext() == null) { 75 return null; 76 } 77 78 List<ResolveInfo> launchers = getTargetContext().getPackageManager() 79 .queryIntentActivities(getHomeIntentInPackage(getTargetContext()), 0); 80 if (launchers.size() != 1) { 81 return null; 82 } 83 return launchers.get(0).activityInfo; 84 } 85 getOverviewComponentName()86 public static ComponentName getOverviewComponentName() { 87 Resources res = Resources.getSystem(); 88 int id = res.getIdentifier("config_recentsComponentName", "string", "android"); 89 if (id != 0) { 90 return ComponentName.unflattenFromString(res.getString(id)); 91 } 92 return new ComponentName("com.android.systemui", 93 "com.android.systemui.recents.RecentsActivity"); 94 } 95 getOverviewPackageName()96 public static String getOverviewPackageName() { 97 return getOverviewComponentName().getPackageName(); 98 } 99 truncateCrash(String text, int maxLines)100 private static String truncateCrash(String text, int maxLines) { 101 String[] lines = text.split("\\r?\\n"); 102 StringBuilder ret = new StringBuilder(); 103 for (int i = 0; i < maxLines && i < lines.length; i++) { 104 ret.append(lines[i]); 105 ret.append('\n'); 106 } 107 if (lines.length > maxLines) { 108 ret.append("... "); 109 ret.append(lines.length - maxLines); 110 ret.append(" more lines truncated ...\n"); 111 } 112 return ret.toString(); 113 } 114 checkCrash(Context context, String label, long startTime)115 private static String checkCrash(Context context, String label, long startTime) { 116 DropBoxManager dropbox = (DropBoxManager) context.getSystemService(Context.DROPBOX_SERVICE); 117 Assert.assertNotNull("Unable access the DropBoxManager service", dropbox); 118 119 long timestamp = startTime; 120 DropBoxManager.Entry entry; 121 StringBuilder errorDetails = new StringBuilder(); 122 while (null != (entry = dropbox.getNextEntry(label, timestamp))) { 123 errorDetails.append("------------------------------\n"); 124 timestamp = entry.getTimeMillis(); 125 errorDetails.append(new Date(timestamp)); 126 errorDetails.append(": "); 127 errorDetails.append(entry.getTag()); 128 errorDetails.append(": "); 129 final String dropboxSnippet = entry.getText(4096); 130 if (dropboxSnippet != null) errorDetails.append(truncateCrash(dropboxSnippet, 40)); 131 errorDetails.append(" ...\n"); 132 entry.close(); 133 } 134 return errorDetails.length() != 0 ? errorDetails.toString() : null; 135 } 136 getSystemHealthMessage(Context context, long startTime)137 public static String getSystemHealthMessage(Context context, long startTime) { 138 try { 139 StringBuilder errors = new StringBuilder(); 140 141 final String[] labels = { 142 "system_app_anr", 143 "system_app_crash", 144 "system_app_native_crash", 145 "system_server_anr", 146 "system_server_crash", 147 "system_server_native_crash", 148 "system_server_watchdog", 149 }; 150 151 for (String label : labels) { 152 final String crash = checkCrash(context, label, startTime); 153 if (crash != null) errors.append(crash); 154 } 155 156 return errors.length() != 0 157 ? "Current time: " + new Date(System.currentTimeMillis()) + "\n" + errors 158 : null; 159 } catch (Exception e) { 160 return null; 161 } 162 } 163 wait(SearchCondition<R> condition, long timeout)164 public static <R> R wait(SearchCondition<R> condition, long timeout) { 165 Log.d(TAG, 166 "TestHelpers.wait, condition=" + timeout + ", time=" + SystemClock.uptimeMillis()); 167 final R result = UiDevice.getInstance(getInstrumentation()).wait(condition, timeout); 168 Log.d(TAG, "TestHelpers.wait, result=" + result + ", time=" + SystemClock.uptimeMillis()); 169 return result; 170 } 171 } 172