12583fc1e069d0a54df46258d360499492d7e86d2Jason Monk/*
22583fc1e069d0a54df46258d360499492d7e86d2Jason Monk * Copyright (C) 2015 The Android Open Source Project
32583fc1e069d0a54df46258d360499492d7e86d2Jason Monk *
42583fc1e069d0a54df46258d360499492d7e86d2Jason Monk * Licensed under the Apache License, Version 2.0 (the "License");
52583fc1e069d0a54df46258d360499492d7e86d2Jason Monk * you may not use this file except in compliance with the License.
62583fc1e069d0a54df46258d360499492d7e86d2Jason Monk * You may obtain a copy of the License at
72583fc1e069d0a54df46258d360499492d7e86d2Jason Monk *
82583fc1e069d0a54df46258d360499492d7e86d2Jason Monk *      http://www.apache.org/licenses/LICENSE-2.0
92583fc1e069d0a54df46258d360499492d7e86d2Jason Monk *
102583fc1e069d0a54df46258d360499492d7e86d2Jason Monk * Unless required by applicable law or agreed to in writing, software
112583fc1e069d0a54df46258d360499492d7e86d2Jason Monk * distributed under the License is distributed on an "AS IS" BASIS,
122583fc1e069d0a54df46258d360499492d7e86d2Jason Monk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132583fc1e069d0a54df46258d360499492d7e86d2Jason Monk * See the License for the specific language governing permissions and
142583fc1e069d0a54df46258d360499492d7e86d2Jason Monk * limitations under the License.
152583fc1e069d0a54df46258d360499492d7e86d2Jason Monk */
162583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
172583fc1e069d0a54df46258d360499492d7e86d2Jason Monkpackage com.android.settings.applications;
182583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
192583fc1e069d0a54df46258d360499492d7e86d2Jason Monkimport android.app.ActivityManager;
202583fc1e069d0a54df46258d360499492d7e86d2Jason Monkimport android.content.Context;
212583fc1e069d0a54df46258d360499492d7e86d2Jason Monkimport android.content.pm.PackageManager;
222583fc1e069d0a54df46258d360499492d7e86d2Jason Monkimport android.os.ParcelFileDescriptor;
232583fc1e069d0a54df46258d360499492d7e86d2Jason Monkimport android.os.RemoteException;
242583fc1e069d0a54df46258d360499492d7e86d2Jason Monkimport android.os.ServiceManager;
252583fc1e069d0a54df46258d360499492d7e86d2Jason Monkimport android.os.SystemClock;
262583fc1e069d0a54df46258d360499492d7e86d2Jason Monkimport android.text.format.Formatter;
272583fc1e069d0a54df46258d360499492d7e86d2Jason Monkimport android.util.ArrayMap;
282583fc1e069d0a54df46258d360499492d7e86d2Jason Monkimport android.util.Log;
292583fc1e069d0a54df46258d360499492d7e86d2Jason Monkimport android.util.SparseArray;
302583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
312583fc1e069d0a54df46258d360499492d7e86d2Jason Monkimport com.android.internal.app.ProcessMap;
32b370a8d580cdc435081155e6ff5e50d6bb9105e7Joe Onoratoimport com.android.internal.app.procstats.DumpUtils;
33b370a8d580cdc435081155e6ff5e50d6bb9105e7Joe Onoratoimport com.android.internal.app.procstats.IProcessStats;
34b370a8d580cdc435081155e6ff5e50d6bb9105e7Joe Onoratoimport com.android.internal.app.procstats.ProcessState;
35b370a8d580cdc435081155e6ff5e50d6bb9105e7Joe Onoratoimport com.android.internal.app.procstats.ProcessStats;
36b370a8d580cdc435081155e6ff5e50d6bb9105e7Joe Onoratoimport com.android.internal.app.procstats.ProcessStats.ProcessDataCollection;
37b370a8d580cdc435081155e6ff5e50d6bb9105e7Joe Onoratoimport com.android.internal.app.procstats.ProcessStats.TotalMemoryUseCollection;
38b370a8d580cdc435081155e6ff5e50d6bb9105e7Joe Onoratoimport com.android.internal.app.procstats.ServiceState;
392583fc1e069d0a54df46258d360499492d7e86d2Jason Monkimport com.android.internal.util.MemInfoReader;
402583fc1e069d0a54df46258d360499492d7e86d2Jason Monkimport com.android.settings.R;
41beb171d2e50f93b5fb78d73b372a4981e13e04ffJason Monkimport com.android.settings.Utils;
422583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
432583fc1e069d0a54df46258d360499492d7e86d2Jason Monkimport java.io.IOException;
442583fc1e069d0a54df46258d360499492d7e86d2Jason Monkimport java.io.InputStream;
452583fc1e069d0a54df46258d360499492d7e86d2Jason Monkimport java.util.ArrayList;
462583fc1e069d0a54df46258d360499492d7e86d2Jason Monkimport java.util.Comparator;
472583fc1e069d0a54df46258d360499492d7e86d2Jason Monkimport java.util.List;
482583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
492583fc1e069d0a54df46258d360499492d7e86d2Jason Monkpublic class ProcStatsData {
502583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
512583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    private static final String TAG = "ProcStatsManager";
522583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
532583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    private static final boolean DEBUG = ProcessStatsUi.DEBUG;
542583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
552583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    private static ProcessStats sStatsXfer;
562583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
572583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    private PackageManager mPm;
582583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    private Context mContext;
592583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    private long memTotalTime;
602583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
612583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    private IProcessStats mProcessStats;
622583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    private ProcessStats mStats;
632583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
642583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    private boolean mUseUss;
652583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    private long mDuration;
662583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
672583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    private int[] mMemStates;
682583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
692583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    private int[] mStates;
702583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
712583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    private MemInfo mMemInfo;
722583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
732583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    private ArrayList<ProcStatsPackageEntry> pkgEntries;
742583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
752583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    public ProcStatsData(Context context, boolean useXfer) {
762583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        mContext = context;
772583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        mPm = context.getPackageManager();
782583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        mProcessStats = IProcessStats.Stub.asInterface(
792583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                ServiceManager.getService(ProcessStats.SERVICE_NAME));
802583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        mMemStates = ProcessStats.ALL_MEM_ADJ;
812583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        mStates = ProcessStats.BACKGROUND_PROC_STATES;
822583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        if (useXfer) {
832583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            mStats = sStatsXfer;
842583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        }
852583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    }
862583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
872583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    public void setTotalTime(int totalTime) {
882583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        memTotalTime = totalTime;
892583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    }
902583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
912583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    public void xferStats() {
922583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        sStatsXfer = mStats;
932583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    }
942583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
952583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    public void setMemStates(int[] memStates) {
962583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        mMemStates = memStates;
972583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        refreshStats(false);
982583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    }
992583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
1002583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    public void setStats(int[] stats) {
1012583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        this.mStates = stats;
1022583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        refreshStats(false);
1032583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    }
1042583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
1052583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    public int getMemState() {
1061de522323fc2b20b86f59819d819708cafdbd2abJason Monk        int factor = mStats.mMemFactor;
1071de522323fc2b20b86f59819d819708cafdbd2abJason Monk        if (factor == ProcessStats.ADJ_NOTHING) {
1081de522323fc2b20b86f59819d819708cafdbd2abJason Monk            return ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1091de522323fc2b20b86f59819d819708cafdbd2abJason Monk        }
1101de522323fc2b20b86f59819d819708cafdbd2abJason Monk        if (factor >= ProcessStats.ADJ_SCREEN_ON) {
1111de522323fc2b20b86f59819d819708cafdbd2abJason Monk            factor -= ProcessStats.ADJ_SCREEN_ON;
1121de522323fc2b20b86f59819d819708cafdbd2abJason Monk        }
1131de522323fc2b20b86f59819d819708cafdbd2abJason Monk        return factor;
1142583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    }
1152583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
1162583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    public MemInfo getMemInfo() {
1172583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        return mMemInfo;
1182583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    }
1192583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
1202583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    public long getElapsedTime() {
1212583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        return mStats.mTimePeriodEndRealtime - mStats.mTimePeriodStartRealtime;
1222583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    }
1232583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
1242583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    public void setDuration(long duration) {
1252583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        if (duration != mDuration) {
1262583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            mDuration = duration;
1272583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            refreshStats(true);
1282583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        }
1292583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    }
1302583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
1312583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    public long getDuration() {
1322583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        return mDuration;
1332583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    }
1342583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
1352583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    public List<ProcStatsPackageEntry> getEntries() {
1362583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        return pkgEntries;
1372583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    }
1382583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
1392583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    public void refreshStats(boolean forceLoad) {
1402583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        if (mStats == null || forceLoad) {
1412583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            load();
1422583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        }
1432583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
1442583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        pkgEntries = new ArrayList<>();
1452583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
1462583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        long now = SystemClock.uptimeMillis();
1472583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
148b370a8d580cdc435081155e6ff5e50d6bb9105e7Joe Onorato        memTotalTime = DumpUtils.dumpSingleTime(null, null, mStats.mMemFactorDurations,
1492583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                mStats.mMemFactor, mStats.mStartTime, now);
1502583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
1512583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        ProcessStats.TotalMemoryUseCollection totalMem = new ProcessStats.TotalMemoryUseCollection(
1522583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                ProcessStats.ALL_SCREEN_ADJ, mMemStates);
1532583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        mStats.computeTotalMemoryUse(totalMem, now);
1542583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
1552583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        mMemInfo = new MemInfo(mContext, totalMem, memTotalTime);
1562583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
1572583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        ProcessDataCollection bgTotals = new ProcessDataCollection(
1582583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                ProcessStats.ALL_SCREEN_ADJ, mMemStates, mStates);
1592583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        ProcessDataCollection runTotals = new ProcessDataCollection(
1602583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                ProcessStats.ALL_SCREEN_ADJ, mMemStates, ProcessStats.NON_CACHED_PROC_STATES);
1612583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
1622583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        createPkgMap(getProcs(bgTotals, runTotals), bgTotals, runTotals);
163a24b836e8534a617fb8184ba94140286618f4f65Dianne Hackborn        if (totalMem.sysMemZRamWeight > 0 && !totalMem.hasSwappedOutPss) {
16430bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn            distributeZRam(totalMem.sysMemZRamWeight);
16530bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn        }
1662583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
1672583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        ProcStatsPackageEntry osPkg = createOsEntry(bgTotals, runTotals, totalMem,
1682583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                mMemInfo.baseCacheRam);
1692583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        pkgEntries.add(osPkg);
1702583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    }
1712583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
1722583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    private void createPkgMap(ArrayList<ProcStatsEntry> procEntries, ProcessDataCollection bgTotals,
1732583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            ProcessDataCollection runTotals) {
1742583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        // Combine processes into packages.
1752583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        ArrayMap<String, ProcStatsPackageEntry> pkgMap = new ArrayMap<>();
1762583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        for (int i = procEntries.size() - 1; i >= 0; i--) {
1772583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            ProcStatsEntry proc = procEntries.get(i);
1782583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            proc.evaluateTargetPackage(mPm, mStats, bgTotals, runTotals, sEntryCompare, mUseUss);
1792583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            ProcStatsPackageEntry pkg = pkgMap.get(proc.mBestTargetPackage);
1802583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            if (pkg == null) {
1812583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                pkg = new ProcStatsPackageEntry(proc.mBestTargetPackage, memTotalTime);
1822583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                pkgMap.put(proc.mBestTargetPackage, pkg);
1832583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                pkgEntries.add(pkg);
1842583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            }
1852583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            pkg.addEntry(proc);
1862583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        }
1872583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    }
1882583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
18930bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn    private void distributeZRam(double zramWeight) {
19030bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn        // Distribute kernel's Z-Ram across processes, based on how much they have been running.
19130bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn        // The idea is that the memory used by the kernel for this is not really the kernel's
19230bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn        // responsibility, but that of whoever got swapped in to it...  and we will take how
19330bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn        // much a process runs for as a sign of the proportion of Z-Ram it is responsible for.
19430bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn
19530bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn        long zramMem = (long) (zramWeight / memTotalTime);
19630bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn        long totalTime = 0;
19730bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn        for (int i = pkgEntries.size() - 1; i >= 0; i--) {
19830bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn            ProcStatsPackageEntry entry = pkgEntries.get(i);
19930bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn            for (int j = entry.mEntries.size() - 1; j >= 0; j--) {
20030bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn                ProcStatsEntry proc = entry.mEntries.get(j);
20130bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn                totalTime += proc.mRunDuration;
20230bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn            }
20330bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn        }
20430bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn        for (int i = pkgEntries.size() - 1; i >= 0 && totalTime > 0; i--) {
20530bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn            ProcStatsPackageEntry entry = pkgEntries.get(i);
20630bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn            long pkgRunTime = 0;
207b6c7b050565b259eb098cb2a701254b6676aae1cDianne Hackborn            long maxRunTime = 0;
20830bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn            for (int j = entry.mEntries.size() - 1; j >= 0; j--) {
20930bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn                ProcStatsEntry proc = entry.mEntries.get(j);
21030bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn                pkgRunTime += proc.mRunDuration;
211b6c7b050565b259eb098cb2a701254b6676aae1cDianne Hackborn                if (proc.mRunDuration > maxRunTime) {
212b6c7b050565b259eb098cb2a701254b6676aae1cDianne Hackborn                    maxRunTime = proc.mRunDuration;
213b6c7b050565b259eb098cb2a701254b6676aae1cDianne Hackborn                }
21430bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn            }
21530bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn            long pkgZRam = (zramMem*pkgRunTime)/totalTime;
21630bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn            if (pkgZRam > 0) {
21730bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn                zramMem -= pkgZRam;
21830bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn                totalTime -= pkgRunTime;
21930bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn                ProcStatsEntry procEntry = new ProcStatsEntry(entry.mPackage, 0,
220b6c7b050565b259eb098cb2a701254b6676aae1cDianne Hackborn                        mContext.getString(R.string.process_stats_os_zram), maxRunTime,
221b6c7b050565b259eb098cb2a701254b6676aae1cDianne Hackborn                        pkgZRam, memTotalTime);
22230bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn                procEntry.evaluateTargetPackage(mPm, mStats, null, null, sEntryCompare, mUseUss);
22330bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn                entry.addEntry(procEntry);
22430bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn            }
22530bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn        }
22630bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn    }
22730bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn
2282583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    private ProcStatsPackageEntry createOsEntry(ProcessDataCollection bgTotals,
2292583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            ProcessDataCollection runTotals, TotalMemoryUseCollection totalMem, long baseCacheRam) {
2302583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        // Add in fake entry representing the OS itself.
2312583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        ProcStatsPackageEntry osPkg = new ProcStatsPackageEntry("os", memTotalTime);
2322583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        ProcStatsEntry osEntry;
2332583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        if (totalMem.sysMemNativeWeight > 0) {
234beb171d2e50f93b5fb78d73b372a4981e13e04ffJason Monk            osEntry = new ProcStatsEntry(Utils.OS_PKG, 0,
2352583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                    mContext.getString(R.string.process_stats_os_native), memTotalTime,
236b6c7b050565b259eb098cb2a701254b6676aae1cDianne Hackborn                    (long) (totalMem.sysMemNativeWeight / memTotalTime), memTotalTime);
2372583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            osEntry.evaluateTargetPackage(mPm, mStats, bgTotals, runTotals, sEntryCompare, mUseUss);
2382583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            osPkg.addEntry(osEntry);
2392583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        }
2402583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        if (totalMem.sysMemKernelWeight > 0) {
241beb171d2e50f93b5fb78d73b372a4981e13e04ffJason Monk            osEntry = new ProcStatsEntry(Utils.OS_PKG, 0,
2422583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                    mContext.getString(R.string.process_stats_os_kernel), memTotalTime,
243b6c7b050565b259eb098cb2a701254b6676aae1cDianne Hackborn                    (long) (totalMem.sysMemKernelWeight / memTotalTime), memTotalTime);
2442583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            osEntry.evaluateTargetPackage(mPm, mStats, bgTotals, runTotals, sEntryCompare, mUseUss);
2452583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            osPkg.addEntry(osEntry);
2462583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        }
24730bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn        /*  Turned off now -- zram is being distributed across running apps.
2482583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        if (totalMem.sysMemZRamWeight > 0) {
249beb171d2e50f93b5fb78d73b372a4981e13e04ffJason Monk            osEntry = new ProcStatsEntry(Utils.OS_PKG, 0,
2502583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                    mContext.getString(R.string.process_stats_os_zram), memTotalTime,
2512583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                    (long) (totalMem.sysMemZRamWeight / memTotalTime));
2522583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            osEntry.evaluateTargetPackage(mPm, mStats, bgTotals, runTotals, sEntryCompare, mUseUss);
2532583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            osPkg.addEntry(osEntry);
2542583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        }
25530bbd902dd98197fd39b4e43bf8cb5027c49984bDianne Hackborn        */
2562583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        if (baseCacheRam > 0) {
257beb171d2e50f93b5fb78d73b372a4981e13e04ffJason Monk            osEntry = new ProcStatsEntry(Utils.OS_PKG, 0,
2582583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                    mContext.getString(R.string.process_stats_os_cache), memTotalTime,
259b6c7b050565b259eb098cb2a701254b6676aae1cDianne Hackborn                    baseCacheRam / 1024, memTotalTime);
2602583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            osEntry.evaluateTargetPackage(mPm, mStats, bgTotals, runTotals, sEntryCompare, mUseUss);
2612583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            osPkg.addEntry(osEntry);
2622583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        }
2632583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        return osPkg;
2642583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    }
2652583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
2662583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    private ArrayList<ProcStatsEntry> getProcs(ProcessDataCollection bgTotals,
2672583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            ProcessDataCollection runTotals) {
2682583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        final ArrayList<ProcStatsEntry> procEntries = new ArrayList<>();
2692583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        if (DEBUG) Log.d(TAG, "-------------------- PULLING PROCESSES");
2702583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
2712583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        final ProcessMap<ProcStatsEntry> entriesMap = new ProcessMap<ProcStatsEntry>();
2722583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        for (int ipkg = 0, N = mStats.mPackages.getMap().size(); ipkg < N; ipkg++) {
2732583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            final SparseArray<SparseArray<ProcessStats.PackageState>> pkgUids = mStats.mPackages
2742583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                    .getMap().valueAt(ipkg);
2752583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            for (int iu = 0; iu < pkgUids.size(); iu++) {
2762583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                final SparseArray<ProcessStats.PackageState> vpkgs = pkgUids.valueAt(iu);
2772583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                for (int iv = 0; iv < vpkgs.size(); iv++) {
2782583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                    final ProcessStats.PackageState st = vpkgs.valueAt(iv);
2792583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                    for (int iproc = 0; iproc < st.mProcesses.size(); iproc++) {
280b370a8d580cdc435081155e6ff5e50d6bb9105e7Joe Onorato                        final ProcessState pkgProc = st.mProcesses.valueAt(iproc);
281b370a8d580cdc435081155e6ff5e50d6bb9105e7Joe Onorato                        final ProcessState proc = mStats.mProcesses.get(pkgProc.getName(),
282b370a8d580cdc435081155e6ff5e50d6bb9105e7Joe Onorato                                pkgProc.getUid());
2832583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                        if (proc == null) {
2842583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                            Log.w(TAG, "No process found for pkg " + st.mPackageName
285b370a8d580cdc435081155e6ff5e50d6bb9105e7Joe Onorato                                    + "/" + st.mUid + " proc name " + pkgProc.getName());
2862583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                            continue;
2872583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                        }
288b370a8d580cdc435081155e6ff5e50d6bb9105e7Joe Onorato                        ProcStatsEntry ent = entriesMap.get(proc.getName(), proc.getUid());
2892583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                        if (ent == null) {
2902583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                            ent = new ProcStatsEntry(proc, st.mPackageName, bgTotals, runTotals,
2912583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                                    mUseUss);
2922583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                            if (ent.mRunWeight > 0) {
293b370a8d580cdc435081155e6ff5e50d6bb9105e7Joe Onorato                                if (DEBUG) Log.d(TAG, "Adding proc " + proc.getName() + "/"
294b370a8d580cdc435081155e6ff5e50d6bb9105e7Joe Onorato                                            + proc.getUid() + ": time="
2952583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                                            + ProcessStatsUi.makeDuration(ent.mRunDuration) + " ("
2962583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                                            + ((((double) ent.mRunDuration) / memTotalTime) * 100)
2972583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                                            + "%)"
2982583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                                            + " pss=" + ent.mAvgRunMem);
299b370a8d580cdc435081155e6ff5e50d6bb9105e7Joe Onorato                                entriesMap.put(proc.getName(), proc.getUid(), ent);
3002583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                                procEntries.add(ent);
3012583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                            }
3022583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                        } else {
3032583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                            ent.addPackage(st.mPackageName);
3042583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                        }
3052583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                    }
3062583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                }
3072583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            }
3082583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        }
3092583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
3102583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        if (DEBUG) Log.d(TAG, "-------------------- MAPPING SERVICES");
3112583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
3122583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        // Add in service info.
3132583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        for (int ip = 0, N = mStats.mPackages.getMap().size(); ip < N; ip++) {
3142583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            SparseArray<SparseArray<ProcessStats.PackageState>> uids = mStats.mPackages.getMap()
3152583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                    .valueAt(ip);
3162583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            for (int iu = 0; iu < uids.size(); iu++) {
3172583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                SparseArray<ProcessStats.PackageState> vpkgs = uids.valueAt(iu);
3182583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                for (int iv = 0; iv < vpkgs.size(); iv++) {
3192583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                    ProcessStats.PackageState ps = vpkgs.valueAt(iv);
3202583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                    for (int is = 0, NS = ps.mServices.size(); is < NS; is++) {
321b370a8d580cdc435081155e6ff5e50d6bb9105e7Joe Onorato                        ServiceState ss = ps.mServices.valueAt(is);
322b370a8d580cdc435081155e6ff5e50d6bb9105e7Joe Onorato                        if (ss.getProcessName() != null) {
323b370a8d580cdc435081155e6ff5e50d6bb9105e7Joe Onorato                            ProcStatsEntry ent = entriesMap.get(ss.getProcessName(),
3242583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                                    uids.keyAt(iu));
3252583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                            if (ent != null) {
3262583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                                if (DEBUG) Log.d(TAG, "Adding service " + ps.mPackageName
327b370a8d580cdc435081155e6ff5e50d6bb9105e7Joe Onorato                                            + "/" + ss.getName() + "/" + uids.keyAt(iu)
328b370a8d580cdc435081155e6ff5e50d6bb9105e7Joe Onorato                                            + " to proc " + ss.getProcessName());
3292583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                                ent.addService(ss);
3302583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                            } else {
331b370a8d580cdc435081155e6ff5e50d6bb9105e7Joe Onorato                                Log.w(TAG, "No process " + ss.getProcessName() + "/"
332b370a8d580cdc435081155e6ff5e50d6bb9105e7Joe Onorato                                        + uids.keyAt(iu) + " for service " + ss.getName());
3332583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                            }
3342583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                        }
3352583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                    }
3362583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                }
3372583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            }
3382583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        }
3392583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
3402583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        return procEntries;
3412583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    }
3422583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
3432583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    private void load() {
3442583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        try {
3452583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            ParcelFileDescriptor pfd = mProcessStats.getStatsOverTime(mDuration);
3462583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            mStats = new ProcessStats(false);
3472583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
3482583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            mStats.read(is);
3492583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            try {
3502583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                is.close();
3512583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            } catch (IOException e) {
3522583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            }
3532583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            if (mStats.mReadError != null) {
3542583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                Log.w(TAG, "Failure reading process stats: " + mStats.mReadError);
3552583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            }
3562583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        } catch (RemoteException e) {
3572583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            Log.e(TAG, "RemoteException:", e);
3582583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        }
3592583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    }
3602583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
3612583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    public static class MemInfo {
362dc252eb7b1169dbdde6b6bf8821eb6f8babd4d26Jason Monk        public double realUsedRam;
363dc252eb7b1169dbdde6b6bf8821eb6f8babd4d26Jason Monk        public double realFreeRam;
364dc252eb7b1169dbdde6b6bf8821eb6f8babd4d26Jason Monk        public double realTotalRam;
3652583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        long baseCacheRam;
3662583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
3672583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        double[] mMemStateWeights = new double[ProcessStats.STATE_COUNT];
3682583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        double freeWeight;
3692583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        double usedWeight;
3702583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        double weightToRam;
3712583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        double totalRam;
3722583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        double totalScale;
3731de522323fc2b20b86f59819d819708cafdbd2abJason Monk        long memTotalTime;
3742583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
3752583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        private MemInfo(Context context, ProcessStats.TotalMemoryUseCollection totalMem,
3762583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                long memTotalTime) {
3771de522323fc2b20b86f59819d819708cafdbd2abJason Monk            this.memTotalTime = memTotalTime;
3782583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            calculateWeightInfo(context, totalMem, memTotalTime);
3792583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
3802583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            double usedRam = (usedWeight * 1024) / memTotalTime;
3812583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            double freeRam = (freeWeight * 1024) / memTotalTime;
3822583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            totalRam = usedRam + freeRam;
3832583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            totalScale = realTotalRam / totalRam;
3842583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            weightToRam = totalScale / memTotalTime * 1024;
3852583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
3862583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            realUsedRam = usedRam * totalScale;
3872583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            realFreeRam = freeRam * totalScale;
3882583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            if (DEBUG) {
3892583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                Log.i(TAG, "Scaled Used RAM: " + Formatter.formatShortFileSize(context,
3902583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                        (long) realUsedRam));
3912583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                Log.i(TAG, "Scaled Free RAM: " + Formatter.formatShortFileSize(context,
3922583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                        (long) realFreeRam));
3932583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            }
3942583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            if (DEBUG) {
3952583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                Log.i(TAG, "Adj Scaled Used RAM: " + Formatter.formatShortFileSize(context,
3962583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                        (long) realUsedRam));
3972583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                Log.i(TAG, "Adj Scaled Free RAM: " + Formatter.formatShortFileSize(context,
3982583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                        (long) realFreeRam));
3992583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            }
4002583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
4012583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
4022583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryInfo(
4032583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                    memInfo);
4042583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            if (memInfo.hiddenAppThreshold >= realFreeRam) {
4052583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                realUsedRam = freeRam;
4062583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                realFreeRam = 0;
4072583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                baseCacheRam = (long) realFreeRam;
4082583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            } else {
4092583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                realUsedRam += memInfo.hiddenAppThreshold;
4102583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                realFreeRam -= memInfo.hiddenAppThreshold;
4112583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                baseCacheRam = memInfo.hiddenAppThreshold;
4122583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            }
4132583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        }
4142583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
4152583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        private void calculateWeightInfo(Context context, TotalMemoryUseCollection totalMem,
4162583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                long memTotalTime) {
4172583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            MemInfoReader memReader = new MemInfoReader();
4182583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            memReader.readMemInfo();
4192583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            realTotalRam = memReader.getTotalSize();
4202583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            freeWeight = totalMem.sysMemFreeWeight + totalMem.sysMemCachedWeight;
421a24b836e8534a617fb8184ba94140286618f4f65Dianne Hackborn            usedWeight = totalMem.sysMemKernelWeight + totalMem.sysMemNativeWeight;
422a24b836e8534a617fb8184ba94140286618f4f65Dianne Hackborn            if (!totalMem.hasSwappedOutPss) {
423a24b836e8534a617fb8184ba94140286618f4f65Dianne Hackborn                usedWeight += totalMem.sysMemZRamWeight;
424a24b836e8534a617fb8184ba94140286618f4f65Dianne Hackborn            }
4252583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            for (int i = 0; i < ProcessStats.STATE_COUNT; i++) {
4262583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                if (i == ProcessStats.STATE_SERVICE_RESTARTING) {
4272583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                    // These don't really run.
4282583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                    mMemStateWeights[i] = 0;
4292583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                } else {
4302583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                    mMemStateWeights[i] = totalMem.processStateWeight[i];
4312583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                    if (i >= ProcessStats.STATE_HOME) {
4322583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                        freeWeight += totalMem.processStateWeight[i];
4332583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                    } else {
4342583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                        usedWeight += totalMem.processStateWeight[i];
4352583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                    }
4362583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                }
4372583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            }
4382583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            if (DEBUG) {
4392583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                Log.i(TAG, "Used RAM: " + Formatter.formatShortFileSize(context,
4402583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                        (long) ((usedWeight * 1024) / memTotalTime)));
4412583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                Log.i(TAG, "Free RAM: " + Formatter.formatShortFileSize(context,
4422583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                        (long) ((freeWeight * 1024) / memTotalTime)));
4432583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                Log.i(TAG, "Total RAM: " + Formatter.formatShortFileSize(context,
4442583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                        (long) (((freeWeight + usedWeight) * 1024) / memTotalTime)));
4452583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            }
4462583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        }
4472583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    }
4482583fc1e069d0a54df46258d360499492d7e86d2Jason Monk
4492583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    final static Comparator<ProcStatsEntry> sEntryCompare = new Comparator<ProcStatsEntry>() {
4502583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        @Override
4512583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        public int compare(ProcStatsEntry lhs, ProcStatsEntry rhs) {
4522583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            if (lhs.mRunWeight < rhs.mRunWeight) {
4532583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                return 1;
4542583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            } else if (lhs.mRunWeight > rhs.mRunWeight) {
4552583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                return -1;
4562583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            } else if (lhs.mRunDuration < rhs.mRunDuration) {
4572583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                return 1;
4582583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            } else if (lhs.mRunDuration > rhs.mRunDuration) {
4592583fc1e069d0a54df46258d360499492d7e86d2Jason Monk                return -1;
4602583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            }
4612583fc1e069d0a54df46258d360499492d7e86d2Jason Monk            return 0;
4622583fc1e069d0a54df46258d360499492d7e86d2Jason Monk        }
4632583fc1e069d0a54df46258d360499492d7e86d2Jason Monk    };
4642583fc1e069d0a54df46258d360499492d7e86d2Jason Monk}
465