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 
MemoryQuery(ActivityManager activityManager)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      */
queryMemory()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 }