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 31 import org.junit.Assert; 32 33 import java.util.Date; 34 import java.util.List; 35 36 public class TestHelpers { 37 38 private static Boolean sIsInLauncherProcess; 39 isInLauncherProcess()40 public static boolean isInLauncherProcess() { 41 if (sIsInLauncherProcess == null) { 42 sIsInLauncherProcess = initIsInLauncherProcess(); 43 } 44 return sIsInLauncherProcess; 45 } 46 initIsInLauncherProcess()47 private static boolean initIsInLauncherProcess() { 48 ActivityInfo info = getLauncherInMyProcess(); 49 50 // If we are in the same process, we can instantiate the class name. 51 try { 52 Class launcherClazz = Class.forName("com.android.launcher3.Launcher"); 53 return launcherClazz.isAssignableFrom(Class.forName(info.name)); 54 } catch (Exception e) { 55 return false; 56 } 57 } 58 getHomeIntentInPackage(Context context)59 public static Intent getHomeIntentInPackage(Context context) { 60 return new Intent(Intent.ACTION_MAIN) 61 .addCategory(Intent.CATEGORY_HOME) 62 .setPackage(context.getPackageName()) 63 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 64 } 65 getLauncherInMyProcess()66 public static ActivityInfo getLauncherInMyProcess() { 67 Instrumentation instrumentation = getInstrumentation(); 68 if (instrumentation.getTargetContext() == null) { 69 return null; 70 } 71 72 List<ResolveInfo> launchers = getTargetContext().getPackageManager() 73 .queryIntentActivities(getHomeIntentInPackage(getTargetContext()), 0); 74 if (launchers.size() != 1) { 75 return null; 76 } 77 return launchers.get(0).activityInfo; 78 } 79 getOverviewComponentName()80 public static ComponentName getOverviewComponentName() { 81 Resources res = Resources.getSystem(); 82 int id = res.getIdentifier("config_recentsComponentName", "string", "android"); 83 if (id != 0) { 84 return ComponentName.unflattenFromString(res.getString(id)); 85 } 86 return new ComponentName("com.android.systemui", 87 "com.android.systemui.recents.RecentsActivity"); 88 } 89 getOverviewPackageName()90 public static String getOverviewPackageName() { 91 return getOverviewComponentName().getPackageName(); 92 } 93 truncateCrash(String text, int maxLines)94 private static String truncateCrash(String text, int maxLines) { 95 String[] lines = text.split("\\r?\\n"); 96 StringBuilder ret = new StringBuilder(); 97 for (int i = 0; i < maxLines && i < lines.length; i++) { 98 ret.append(lines[i]); 99 ret.append('\n'); 100 } 101 if (lines.length > maxLines) { 102 ret.append("... "); 103 ret.append(lines.length - maxLines); 104 ret.append(" more lines truncated ...\n"); 105 } 106 return ret.toString(); 107 } 108 checkCrash(Context context, String label, long startTime)109 private static String checkCrash(Context context, String label, long startTime) { 110 DropBoxManager dropbox = (DropBoxManager) context.getSystemService(Context.DROPBOX_SERVICE); 111 Assert.assertNotNull("Unable access the DropBoxManager service", dropbox); 112 113 long timestamp = startTime; 114 DropBoxManager.Entry entry; 115 StringBuilder errorDetails = new StringBuilder(); 116 while (null != (entry = dropbox.getNextEntry(label, timestamp))) { 117 errorDetails.append("------------------------------\n"); 118 timestamp = entry.getTimeMillis(); 119 errorDetails.append(new Date(timestamp)); 120 errorDetails.append(": "); 121 errorDetails.append(entry.getTag()); 122 errorDetails.append(": "); 123 final String dropboxSnippet = entry.getText(4096); 124 if (dropboxSnippet != null) errorDetails.append(truncateCrash(dropboxSnippet, 40)); 125 errorDetails.append(" ...\n"); 126 entry.close(); 127 } 128 return errorDetails.length() != 0 ? errorDetails.toString() : null; 129 } 130 getSystemHealthMessage(Context context, long startTime)131 public static String getSystemHealthMessage(Context context, long startTime) { 132 try { 133 StringBuilder errors = new StringBuilder(); 134 135 final String[] labels = { 136 "system_app_anr", 137 "system_app_crash", 138 "system_app_native_crash", 139 "system_server_anr", 140 "system_server_crash", 141 "system_server_native_crash", 142 "system_server_watchdog", 143 }; 144 145 for (String label : labels) { 146 final String crash = checkCrash(context, label, startTime); 147 if (crash != null) errors.append(crash); 148 } 149 150 return errors.length() != 0 151 ? "Current time: " + new Date(System.currentTimeMillis()) + "\n" + errors 152 : null; 153 } catch (Exception e) { 154 return null; 155 } 156 } 157 } 158