OSDN Git Service

Clear only keystore credential entires
[android-x86/packages-apps-Settings.git] / src / com / android / settings / applications / ProcStatsData.java
1 /*
2  * Copyright (C) 2015 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.settings.applications;
18
19 import android.app.ActivityManager;
20 import android.content.Context;
21 import android.content.pm.PackageManager;
22 import android.os.ParcelFileDescriptor;
23 import android.os.RemoteException;
24 import android.os.ServiceManager;
25 import android.os.SystemClock;
26 import android.text.format.Formatter;
27 import android.util.ArrayMap;
28 import android.util.Log;
29 import android.util.SparseArray;
30
31 import com.android.internal.app.IProcessStats;
32 import com.android.internal.app.ProcessMap;
33 import com.android.internal.app.ProcessStats;
34 import com.android.internal.app.ProcessStats.ProcessDataCollection;
35 import com.android.internal.app.ProcessStats.TotalMemoryUseCollection;
36 import com.android.internal.util.MemInfoReader;
37 import com.android.settings.R;
38
39 import java.io.IOException;
40 import java.io.InputStream;
41 import java.util.ArrayList;
42 import java.util.Comparator;
43 import java.util.List;
44
45 public class ProcStatsData {
46
47     private static final String TAG = "ProcStatsManager";
48
49     private static final boolean DEBUG = ProcessStatsUi.DEBUG;
50
51     private static ProcessStats sStatsXfer;
52
53     private PackageManager mPm;
54     private Context mContext;
55     private long memTotalTime;
56
57     private IProcessStats mProcessStats;
58     private ProcessStats mStats;
59
60     private int mMemState;
61
62     private boolean mUseUss;
63     private long mDuration;
64
65     private int[] mMemStates;
66
67     private int[] mStates;
68
69     private MemInfo mMemInfo;
70
71     private ArrayList<ProcStatsPackageEntry> pkgEntries;
72
73     public ProcStatsData(Context context, boolean useXfer) {
74         mContext = context;
75         mPm = context.getPackageManager();
76         mProcessStats = IProcessStats.Stub.asInterface(
77                 ServiceManager.getService(ProcessStats.SERVICE_NAME));
78         mMemStates = ProcessStats.ALL_MEM_ADJ;
79         mStates = ProcessStats.BACKGROUND_PROC_STATES;
80         if (useXfer) {
81             mStats = sStatsXfer;
82         }
83     }
84
85     public void setTotalTime(int totalTime) {
86         memTotalTime = totalTime;
87     }
88
89     public void xferStats() {
90         sStatsXfer = mStats;
91     }
92
93     public void setMemStates(int[] memStates) {
94         mMemStates = memStates;
95         refreshStats(false);
96     }
97
98     public void setStats(int[] stats) {
99         this.mStates = stats;
100         refreshStats(false);
101     }
102
103     public int getMemState() {
104         int factor = mStats.mMemFactor;
105         if (factor == ProcessStats.ADJ_NOTHING) {
106             return ProcessStats.ADJ_MEM_FACTOR_NORMAL;
107         }
108         if (factor >= ProcessStats.ADJ_SCREEN_ON) {
109             factor -= ProcessStats.ADJ_SCREEN_ON;
110         }
111         return factor;
112     }
113
114     public MemInfo getMemInfo() {
115         return mMemInfo;
116     }
117
118     public long getElapsedTime() {
119         return mStats.mTimePeriodEndRealtime - mStats.mTimePeriodStartRealtime;
120     }
121
122     public void setDuration(long duration) {
123         if (duration != mDuration) {
124             mDuration = duration;
125             refreshStats(true);
126         }
127     }
128
129     public long getDuration() {
130         return mDuration;
131     }
132
133     public List<ProcStatsPackageEntry> getEntries() {
134         return pkgEntries;
135     }
136
137     public void refreshStats(boolean forceLoad) {
138         if (mStats == null || forceLoad) {
139             load();
140         }
141
142         pkgEntries = new ArrayList<>();
143
144         long now = SystemClock.uptimeMillis();
145
146         memTotalTime = ProcessStats.dumpSingleTime(null, null, mStats.mMemFactorDurations,
147                 mStats.mMemFactor, mStats.mStartTime, now);
148
149         ProcessStats.TotalMemoryUseCollection totalMem = new ProcessStats.TotalMemoryUseCollection(
150                 ProcessStats.ALL_SCREEN_ADJ, mMemStates);
151         mStats.computeTotalMemoryUse(totalMem, now);
152
153         mMemInfo = new MemInfo(mContext, totalMem, memTotalTime);
154
155         ProcessDataCollection bgTotals = new ProcessDataCollection(
156                 ProcessStats.ALL_SCREEN_ADJ, mMemStates, mStates);
157         ProcessDataCollection runTotals = new ProcessDataCollection(
158                 ProcessStats.ALL_SCREEN_ADJ, mMemStates, ProcessStats.NON_CACHED_PROC_STATES);
159
160         createPkgMap(getProcs(bgTotals, runTotals), bgTotals, runTotals);
161
162         ProcStatsPackageEntry osPkg = createOsEntry(bgTotals, runTotals, totalMem,
163                 mMemInfo.baseCacheRam);
164         pkgEntries.add(osPkg);
165     }
166
167     private void createPkgMap(ArrayList<ProcStatsEntry> procEntries, ProcessDataCollection bgTotals,
168             ProcessDataCollection runTotals) {
169         // Combine processes into packages.
170         ArrayMap<String, ProcStatsPackageEntry> pkgMap = new ArrayMap<>();
171         for (int i = procEntries.size() - 1; i >= 0; i--) {
172             ProcStatsEntry proc = procEntries.get(i);
173             proc.evaluateTargetPackage(mPm, mStats, bgTotals, runTotals, sEntryCompare, mUseUss);
174             ProcStatsPackageEntry pkg = pkgMap.get(proc.mBestTargetPackage);
175             if (pkg == null) {
176                 pkg = new ProcStatsPackageEntry(proc.mBestTargetPackage, memTotalTime);
177                 pkgMap.put(proc.mBestTargetPackage, pkg);
178                 pkgEntries.add(pkg);
179             }
180             pkg.addEntry(proc);
181         }
182     }
183
184     private ProcStatsPackageEntry createOsEntry(ProcessDataCollection bgTotals,
185             ProcessDataCollection runTotals, TotalMemoryUseCollection totalMem, long baseCacheRam) {
186         // Add in fake entry representing the OS itself.
187         ProcStatsPackageEntry osPkg = new ProcStatsPackageEntry("os", memTotalTime);
188         ProcStatsEntry osEntry;
189         if (totalMem.sysMemNativeWeight > 0) {
190             osEntry = new ProcStatsEntry("os", 0,
191                     mContext.getString(R.string.process_stats_os_native), memTotalTime,
192                     (long) (totalMem.sysMemNativeWeight / memTotalTime));
193             osEntry.evaluateTargetPackage(mPm, mStats, bgTotals, runTotals, sEntryCompare, mUseUss);
194             osPkg.addEntry(osEntry);
195         }
196         if (totalMem.sysMemKernelWeight > 0) {
197             osEntry = new ProcStatsEntry("os", 0,
198                     mContext.getString(R.string.process_stats_os_kernel), memTotalTime,
199                     (long) (totalMem.sysMemKernelWeight / memTotalTime));
200             osEntry.evaluateTargetPackage(mPm, mStats, bgTotals, runTotals, sEntryCompare, mUseUss);
201             osPkg.addEntry(osEntry);
202         }
203         if (totalMem.sysMemZRamWeight > 0) {
204             osEntry = new ProcStatsEntry("os", 0,
205                     mContext.getString(R.string.process_stats_os_zram), memTotalTime,
206                     (long) (totalMem.sysMemZRamWeight / memTotalTime));
207             osEntry.evaluateTargetPackage(mPm, mStats, bgTotals, runTotals, sEntryCompare, mUseUss);
208             osPkg.addEntry(osEntry);
209         }
210         if (baseCacheRam > 0) {
211             osEntry = new ProcStatsEntry("os", 0,
212                     mContext.getString(R.string.process_stats_os_cache), memTotalTime,
213                     baseCacheRam / 1024);
214             osEntry.evaluateTargetPackage(mPm, mStats, bgTotals, runTotals, sEntryCompare, mUseUss);
215             osPkg.addEntry(osEntry);
216         }
217         return osPkg;
218     }
219
220     private ArrayList<ProcStatsEntry> getProcs(ProcessDataCollection bgTotals,
221             ProcessDataCollection runTotals) {
222         final ArrayList<ProcStatsEntry> procEntries = new ArrayList<>();
223         if (DEBUG) Log.d(TAG, "-------------------- PULLING PROCESSES");
224
225         final ProcessMap<ProcStatsEntry> entriesMap = new ProcessMap<ProcStatsEntry>();
226         for (int ipkg = 0, N = mStats.mPackages.getMap().size(); ipkg < N; ipkg++) {
227             final SparseArray<SparseArray<ProcessStats.PackageState>> pkgUids = mStats.mPackages
228                     .getMap().valueAt(ipkg);
229             for (int iu = 0; iu < pkgUids.size(); iu++) {
230                 final SparseArray<ProcessStats.PackageState> vpkgs = pkgUids.valueAt(iu);
231                 for (int iv = 0; iv < vpkgs.size(); iv++) {
232                     final ProcessStats.PackageState st = vpkgs.valueAt(iv);
233                     for (int iproc = 0; iproc < st.mProcesses.size(); iproc++) {
234                         final ProcessStats.ProcessState pkgProc = st.mProcesses.valueAt(iproc);
235                         final ProcessStats.ProcessState proc = mStats.mProcesses.get(pkgProc.mName,
236                                 pkgProc.mUid);
237                         if (proc == null) {
238                             Log.w(TAG, "No process found for pkg " + st.mPackageName
239                                     + "/" + st.mUid + " proc name " + pkgProc.mName);
240                             continue;
241                         }
242                         ProcStatsEntry ent = entriesMap.get(proc.mName, proc.mUid);
243                         if (ent == null) {
244                             ent = new ProcStatsEntry(proc, st.mPackageName, bgTotals, runTotals,
245                                     mUseUss);
246                             if (ent.mRunWeight > 0) {
247                                 if (DEBUG) Log.d(TAG, "Adding proc " + proc.mName + "/"
248                                             + proc.mUid + ": time="
249                                             + ProcessStatsUi.makeDuration(ent.mRunDuration) + " ("
250                                             + ((((double) ent.mRunDuration) / memTotalTime) * 100)
251                                             + "%)"
252                                             + " pss=" + ent.mAvgRunMem);
253                                 entriesMap.put(proc.mName, proc.mUid, ent);
254                                 procEntries.add(ent);
255                             }
256                         } else {
257                             ent.addPackage(st.mPackageName);
258                         }
259                     }
260                 }
261             }
262         }
263
264         if (DEBUG) Log.d(TAG, "-------------------- MAPPING SERVICES");
265
266         // Add in service info.
267         for (int ip = 0, N = mStats.mPackages.getMap().size(); ip < N; ip++) {
268             SparseArray<SparseArray<ProcessStats.PackageState>> uids = mStats.mPackages.getMap()
269                     .valueAt(ip);
270             for (int iu = 0; iu < uids.size(); iu++) {
271                 SparseArray<ProcessStats.PackageState> vpkgs = uids.valueAt(iu);
272                 for (int iv = 0; iv < vpkgs.size(); iv++) {
273                     ProcessStats.PackageState ps = vpkgs.valueAt(iv);
274                     for (int is = 0, NS = ps.mServices.size(); is < NS; is++) {
275                         ProcessStats.ServiceState ss = ps.mServices.valueAt(is);
276                         if (ss.mProcessName != null) {
277                             ProcStatsEntry ent = entriesMap.get(ss.mProcessName,
278                                     uids.keyAt(iu));
279                             if (ent != null) {
280                                 if (DEBUG) Log.d(TAG, "Adding service " + ps.mPackageName
281                                             + "/" + ss.mName + "/" + uids.keyAt(iu) + " to proc "
282                                             + ss.mProcessName);
283                                 ent.addService(ss);
284                             } else {
285                                 Log.w(TAG, "No process " + ss.mProcessName + "/" + uids.keyAt(iu)
286                                         + " for service " + ss.mName);
287                             }
288                         }
289                     }
290                 }
291             }
292         }
293
294         return procEntries;
295     }
296
297     private void load() {
298         try {
299             mMemState = mProcessStats.getCurrentMemoryState();
300             ParcelFileDescriptor pfd = mProcessStats.getStatsOverTime(mDuration);
301             mStats = new ProcessStats(false);
302             InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
303             mStats.read(is);
304             try {
305                 is.close();
306             } catch (IOException e) {
307             }
308             if (mStats.mReadError != null) {
309                 Log.w(TAG, "Failure reading process stats: " + mStats.mReadError);
310             }
311         } catch (RemoteException e) {
312             Log.e(TAG, "RemoteException:", e);
313         }
314     }
315
316     public static class MemInfo {
317         double realUsedRam;
318         double realFreeRam;
319         double realTotalRam;
320         long baseCacheRam;
321
322         double[] mMemStateWeights = new double[ProcessStats.STATE_COUNT];
323         double freeWeight;
324         double usedWeight;
325         double weightToRam;
326         double totalRam;
327         double totalScale;
328         long memTotalTime;
329
330         private MemInfo(Context context, ProcessStats.TotalMemoryUseCollection totalMem,
331                 long memTotalTime) {
332             this.memTotalTime = memTotalTime;
333             calculateWeightInfo(context, totalMem, memTotalTime);
334
335             double usedRam = (usedWeight * 1024) / memTotalTime;
336             double freeRam = (freeWeight * 1024) / memTotalTime;
337             totalRam = usedRam + freeRam;
338             totalScale = realTotalRam / totalRam;
339             weightToRam = totalScale / memTotalTime * 1024;
340
341             realUsedRam = usedRam * totalScale;
342             realFreeRam = freeRam * totalScale;
343             if (DEBUG) {
344                 Log.i(TAG, "Scaled Used RAM: " + Formatter.formatShortFileSize(context,
345                         (long) realUsedRam));
346                 Log.i(TAG, "Scaled Free RAM: " + Formatter.formatShortFileSize(context,
347                         (long) realFreeRam));
348             }
349             if (DEBUG) {
350                 Log.i(TAG, "Adj Scaled Used RAM: " + Formatter.formatShortFileSize(context,
351                         (long) realUsedRam));
352                 Log.i(TAG, "Adj Scaled Free RAM: " + Formatter.formatShortFileSize(context,
353                         (long) realFreeRam));
354             }
355
356             ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
357             ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryInfo(
358                     memInfo);
359             if (memInfo.hiddenAppThreshold >= realFreeRam) {
360                 realUsedRam = freeRam;
361                 realFreeRam = 0;
362                 baseCacheRam = (long) realFreeRam;
363             } else {
364                 realUsedRam += memInfo.hiddenAppThreshold;
365                 realFreeRam -= memInfo.hiddenAppThreshold;
366                 baseCacheRam = memInfo.hiddenAppThreshold;
367             }
368         }
369
370         private void calculateWeightInfo(Context context, TotalMemoryUseCollection totalMem,
371                 long memTotalTime) {
372             MemInfoReader memReader = new MemInfoReader();
373             memReader.readMemInfo();
374             realTotalRam = memReader.getTotalSize();
375             freeWeight = totalMem.sysMemFreeWeight + totalMem.sysMemCachedWeight;
376             usedWeight = totalMem.sysMemKernelWeight + totalMem.sysMemNativeWeight
377                     + totalMem.sysMemZRamWeight;
378             for (int i = 0; i < ProcessStats.STATE_COUNT; i++) {
379                 if (i == ProcessStats.STATE_SERVICE_RESTARTING) {
380                     // These don't really run.
381                     mMemStateWeights[i] = 0;
382                 } else {
383                     mMemStateWeights[i] = totalMem.processStateWeight[i];
384                     if (i >= ProcessStats.STATE_HOME) {
385                         freeWeight += totalMem.processStateWeight[i];
386                     } else {
387                         usedWeight += totalMem.processStateWeight[i];
388                     }
389                 }
390             }
391             if (DEBUG) {
392                 Log.i(TAG, "Used RAM: " + Formatter.formatShortFileSize(context,
393                         (long) ((usedWeight * 1024) / memTotalTime)));
394                 Log.i(TAG, "Free RAM: " + Formatter.formatShortFileSize(context,
395                         (long) ((freeWeight * 1024) / memTotalTime)));
396                 Log.i(TAG, "Total RAM: " + Formatter.formatShortFileSize(context,
397                         (long) (((freeWeight + usedWeight) * 1024) / memTotalTime)));
398             }
399         }
400     }
401
402     final static Comparator<ProcStatsEntry> sEntryCompare = new Comparator<ProcStatsEntry>() {
403         @Override
404         public int compare(ProcStatsEntry lhs, ProcStatsEntry rhs) {
405             if (lhs.mRunWeight < rhs.mRunWeight) {
406                 return 1;
407             } else if (lhs.mRunWeight > rhs.mRunWeight) {
408                 return -1;
409             } else if (lhs.mRunDuration < rhs.mRunDuration) {
410                 return 1;
411             } else if (lhs.mRunDuration > rhs.mRunDuration) {
412                 return -1;
413             }
414             return 0;
415         }
416     };
417 }