1 /* 2 * Copyright (C) 2014 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.camera.app; 18 19 import android.app.ActivityManager; 20 import android.os.Debug; 21 import android.os.Process; 22 import android.os.SystemClock; 23 24 import com.android.camera.debug.Log; 25 26 import java.util.HashMap; 27 28 /** 29 * Queries the current memory consumption of the app. 30 */ 31 public class MemoryQuery { 32 private static final Log.Tag TAG = new Log.Tag("MemoryQuery"); 33 private final long BYTES_IN_KILOBYTE = 1024; 34 private final long BYTES_IN_MEGABYTE = BYTES_IN_KILOBYTE * BYTES_IN_KILOBYTE; 35 36 public static final String KEY_TIMESTAMP = "timestamp"; 37 public static final String KEY_MEMORY_AVAILABLE = "availMem"; 38 public static final String KEY_TOTAL_MEMORY = "totalMem"; 39 public static final String KEY_TOTAL_PSS = "totalPSS"; 40 public static final String KEY_NATIVE_PSS = "nativePSS"; 41 public static final String KEY_DALVIK_PSS = "dalvikPSS"; 42 public static final String KEY_OTHER_PSS = "otherPSS"; 43 public static final String KEY_THRESHOLD = "threshold"; 44 public static final String KEY_LOW_MEMORY = "lowMemory"; 45 public static final String KEY_LAST_TRIM_LEVEL = "lastTrimLevel"; 46 public static final String KEY_TOTAL_PRIVATE_DIRTY = "totalPrivateDirty"; 47 public static final String KEY_TOTAL_SHARED_DIRTY = "totalSharedDirty"; 48 public static final String KEY_MEMORY_CLASS = "memoryClass"; 49 public static final String KEY_LARGE_MEMORY_CLASS = "largeMemoryClass"; 50 51 public static final String REPORT_LABEL_LAUNCH = "launch"; 52 53 private ActivityManager mActivityManager; 54 55 public MemoryQuery(ActivityManager activityManager) { 56 mActivityManager = activityManager; 57 } 58 59 /** 60 * Measures the current memory consumption and thresholds of the app, from 61 * the ActivityManager and Debug.MemoryInfo, 62 * 63 * @return HashMap of memory metrics keyed by string labels. 64 */ 65 public HashMap queryMemory() { 66 // Get ActivityManager.MemoryInfo. 67 int memoryClass = mActivityManager.getMemoryClass(); 68 int largeMemoryClass = mActivityManager.getLargeMemoryClass(); 69 ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); 70 mActivityManager.getMemoryInfo(memoryInfo); 71 long availMem = memoryInfo.availMem / BYTES_IN_MEGABYTE; 72 long totalMem = memoryInfo.totalMem / BYTES_IN_MEGABYTE; 73 long threshold = memoryInfo.threshold / BYTES_IN_MEGABYTE; 74 boolean lowMemory = memoryInfo.lowMemory; 75 76 // Get ActivityManager.RunningAppProcessInfo. 77 ActivityManager.RunningAppProcessInfo info = new ActivityManager.RunningAppProcessInfo(); 78 ActivityManager.getMyMemoryState(info); 79 80 // Retrieve a list of all running processes. Get the app PID. 81 int appPID = Process.myPid(); 82 83 // Get ActivityManager.getProcessMemoryInfo for the app PID. 84 long timestamp = SystemClock.elapsedRealtime(); 85 long totalPrivateDirty = 0L; 86 long totalSharedDirty = 0L; 87 long totalPSS = 0L; 88 long nativePSS = 0L; 89 long dalvikPSS = 0L; 90 long otherPSS = 0L; 91 92 if (appPID != 0) { 93 int pids[] = new int[1]; 94 pids[0] = appPID; 95 Debug.MemoryInfo[] memoryInfoArray = mActivityManager.getProcessMemoryInfo(pids); 96 totalPrivateDirty = memoryInfoArray[0].getTotalPrivateDirty() / BYTES_IN_KILOBYTE; 97 totalSharedDirty = memoryInfoArray[0].getTotalSharedDirty() / BYTES_IN_KILOBYTE; 98 totalPSS = memoryInfoArray[0].getTotalPss() / BYTES_IN_KILOBYTE; 99 nativePSS = memoryInfoArray[0].nativePss / BYTES_IN_KILOBYTE; 100 dalvikPSS = memoryInfoArray[0].dalvikPss / BYTES_IN_KILOBYTE; 101 otherPSS = memoryInfoArray[0].otherPss / BYTES_IN_KILOBYTE; 102 } 103 104 HashMap outputData = new HashMap(); 105 outputData.put(KEY_TIMESTAMP, new Long(timestamp)); 106 outputData.put(KEY_MEMORY_AVAILABLE, new Long(availMem)); 107 outputData.put(KEY_TOTAL_MEMORY, new Long(totalMem)); 108 outputData.put(KEY_TOTAL_PSS, new Long(totalPSS)); 109 outputData.put(KEY_LAST_TRIM_LEVEL, new Integer(info.lastTrimLevel)); 110 outputData.put(KEY_TOTAL_PRIVATE_DIRTY, new Long(totalPrivateDirty)); 111 outputData.put(KEY_TOTAL_SHARED_DIRTY, new Long(totalSharedDirty)); 112 outputData.put(KEY_MEMORY_CLASS, new Long(memoryClass)); 113 outputData.put(KEY_LARGE_MEMORY_CLASS, new Long(largeMemoryClass)); 114 outputData.put(KEY_NATIVE_PSS, new Long(nativePSS)); 115 outputData.put(KEY_DALVIK_PSS, new Long(dalvikPSS)); 116 outputData.put(KEY_OTHER_PSS, new Long(otherPSS)); 117 outputData.put(KEY_THRESHOLD, new Long(threshold)); 118 outputData.put(KEY_LOW_MEMORY, new Boolean(lowMemory)); 119 120 Log.d(TAG, String.format("timestamp=%d, availMem=%d, totalMem=%d, totalPSS=%d, " + 121 "lastTrimLevel=%d, largeMemoryClass=%d, nativePSS=%d, dalvikPSS=%d, otherPSS=%d," + 122 "threshold=%d, lowMemory=%s", timestamp, availMem, totalMem, totalPSS, 123 info.lastTrimLevel, largeMemoryClass, nativePSS, dalvikPSS, otherPSS, 124 threshold, lowMemory)); 125 126 return outputData; 127 } 128 }