void deleteVisibleLeak() { Leak visibleLeak = getVisibleLeak(); File heapDumpFile = visibleLeak.heapDump.heapDumpFile; File resultFile = visibleLeak.resultFile; boolean resultDeleted = resultFile.delete(); if (!resultDeleted) { CanaryLog.d("Could not delete result file %s", resultFile.getPath()); } boolean heapDumpDeleted = heapDumpFile.delete(); if (!heapDumpDeleted) { CanaryLog.d("Could not delete heap dump file %s", heapDumpFile.getPath()); } visibleLeakRefKey = null; leaks.remove(visibleLeak); updateUi(); }
@Override protected void onHandleIntent(Intent intent) { if (intent == null) { CanaryLog.d("HeapAnalyzerService received a null intent, ignoring."); return; } String listenerClassName = intent.getStringExtra(LISTENER_CLASS_EXTRA); HeapDump heapDump = (HeapDump) intent.getSerializableExtra(HEAPDUMP_EXTRA); HeapAnalyzer heapAnalyzer = new HeapAnalyzer(heapDump.excludedRefs); AnalysisResult result = heapAnalyzer.checkForLeak(heapDump.heapDumpFile, heapDump.referenceKey); AbstractAnalysisResultService.sendResultToListener(this, listenerClassName, heapDump, result); }
void deleteAllLeaks() { File leakDirectory = leakDirectoryProvider(DisplayLeakActivity.this).leakDirectory(); File[] files = leakDirectory.listFiles(); if (files != null) { for (File file : files) { boolean deleted = file.delete(); if (!deleted) { CanaryLog.d("Could not delete file %s", file.getPath()); } } } leaks = Collections.emptyList(); updateUi(); }
public static boolean isInServiceProcess(Context context, Class<? extends Service> serviceClass) { PackageManager packageManager = context.getPackageManager(); PackageInfo packageInfo; try { packageInfo = packageManager.getPackageInfo(context.getPackageName(), GET_SERVICES); } catch (Exception e) { CanaryLog.d(e, "Could not get package info for %s", context.getPackageName()); return false; } String mainProcess = packageInfo.applicationInfo.processName; ComponentName component = new ComponentName(context, serviceClass); ServiceInfo serviceInfo; try { serviceInfo = packageManager.getServiceInfo(component, 0); } catch (PackageManager.NameNotFoundException ignored) { // Service is disabled. return false; } if (serviceInfo.processName.equals(mainProcess)) { CanaryLog.d("Did not expect service %s to run in main process %s", serviceClass, mainProcess); // Technically we are in the service process, but we're not in the service dedicated process. return false; } int myPid = android.os.Process.myPid(); ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); ActivityManager.RunningAppProcessInfo myProcess = null; List<ActivityManager.RunningAppProcessInfo> runningProcesses = activityManager.getRunningAppProcesses(); if (runningProcesses != null) { for (ActivityManager.RunningAppProcessInfo process : runningProcesses) { if (process.pid == myPid) { myProcess = process; break; } } } if (myProcess == null) { CanaryLog.d("Could not find running process for %d", myPid); return false; } return myProcess.processName.equals(serviceInfo.processName); }
@Override public void run() { final List<Leak> leaks = new ArrayList<>(); List<File> files = leakDirectoryProvider.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String filename) { return filename.endsWith(".result"); } }); for (File resultFile : files) { FileInputStream fis = null; try { fis = new FileInputStream(resultFile); ObjectInputStream ois = new ObjectInputStream(fis); HeapDump heapDump = (HeapDump) ois.readObject(); AnalysisResult result = (AnalysisResult) ois.readObject(); leaks.add(new Leak(heapDump, result, resultFile)); } catch (IOException | ClassNotFoundException e) { // Likely a change in the serializable result class. // Let's remove the files, we can't read them anymore. boolean deleted = resultFile.delete(); if (deleted) { CanaryLog.d(e, "Could not read result file %s, deleted it.", resultFile); } else { CanaryLog.d(e, "Could not read result file %s, could not delete it either.", resultFile); } } finally { if (fis != null) { try { fis.close(); } catch (IOException ignored) { } } } } Collections.sort(leaks, new Comparator<Leak>() { @Override public int compare(Leak lhs, Leak rhs) { return Long.valueOf(rhs.resultFile.lastModified()) .compareTo(lhs.resultFile.lastModified()); } }); mainHandler.post(new Runnable() { @Override public void run() { inFlight.remove(LoadLeaks.this); if (activityOrNull != null) { activityOrNull.leaks = leaks; activityOrNull.updateUi(); } } }); }