ProcStatsPackageEntry.java revision 2583fc1e069d0a54df46258d360499492d7e86d2
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 17package com.android.settings.applications; 18 19import android.content.Context; 20import android.content.pm.ApplicationInfo; 21import android.content.pm.PackageManager; 22import android.os.Parcel; 23import android.os.Parcelable; 24 25import com.android.settings.R; 26 27import java.util.ArrayList; 28 29public class ProcStatsPackageEntry implements Parcelable { 30 private static final String TAG = "ProcStatsEntry"; 31 private static boolean DEBUG = ProcessStatsUi.DEBUG; 32 33 private static final float ALWAYS_THRESHOLD = .95f; 34 private static final float SOMETIMES_THRESHOLD = .25f; 35 36 final String mPackage; 37 final ArrayList<ProcStatsEntry> mEntries = new ArrayList<ProcStatsEntry>(); 38 39 long mBgDuration; 40 long mAvgBgMem; 41 long mMaxBgMem; 42 double mBgWeight; 43 long mRunDuration; 44 long mAvgRunMem; 45 long mMaxRunMem; 46 double mRunWeight; 47 48 public ApplicationInfo mUiTargetApp; 49 public String mUiLabel; 50 private long mWindowLength; 51 52 public ProcStatsPackageEntry(String pkg, long windowLength) { 53 mPackage = pkg; 54 mWindowLength = windowLength; 55 } 56 57 public ProcStatsPackageEntry(Parcel in) { 58 mPackage = in.readString(); 59 in.readTypedList(mEntries, ProcStatsEntry.CREATOR); 60 mBgDuration = in.readLong(); 61 mAvgBgMem = in.readLong(); 62 mMaxBgMem = in.readLong(); 63 mBgWeight = in.readDouble(); 64 mRunDuration = in.readLong(); 65 mAvgRunMem = in.readLong(); 66 mMaxRunMem = in.readLong(); 67 mRunWeight = in.readDouble(); 68 } 69 70 public CharSequence getRunningFrequency(Context context) { 71 float amountRunning = mRunDuration / (float) mWindowLength; 72 return getFrequency(amountRunning, context); 73 } 74 75 public CharSequence getBackgroundFrequency(Context context) { 76 float amountRunning = mBgDuration / (float) mWindowLength; 77 return getFrequency(amountRunning, context); 78 } 79 80 public void addEntry(ProcStatsEntry entry) { 81 mEntries.add(entry); 82 } 83 84 public void updateMetrics() { 85 mBgDuration = mAvgBgMem = mMaxBgMem = 0; 86 mBgWeight = 0; 87 mRunDuration = mAvgRunMem = mMaxRunMem = 0; 88 mRunWeight = 0; 89 final int N = mEntries.size(); 90 for (int i=0; i < N; i++) { 91 ProcStatsEntry entry = mEntries.get(i); 92 mBgDuration += entry.mBgDuration; 93 mAvgBgMem += entry.mAvgBgMem * entry.mBgDuration; 94 mBgWeight += entry.mBgWeight; 95 mRunDuration += entry.mRunDuration; 96 mAvgRunMem += entry.mAvgRunMem * entry.mRunDuration; 97 mRunWeight += entry.mRunWeight; 98 99 // Each entry is generally a process or something similar. Since it is extremely 100 // unlikely that any apps are going to avoid running processes at the same time 101 // to avoid memory usage, we will sum the maximum memory usage to create a 102 // hypothetical worst case scenario of memory. 103 mMaxBgMem += entry.mMaxBgMem; 104 mMaxRunMem += entry.mMaxRunMem; 105 } 106 if (mBgDuration != 0) { 107 mAvgBgMem = mAvgBgMem * N / mBgDuration; 108 } 109 if (mRunDuration != 0) { 110 mAvgRunMem = mAvgRunMem * N / mRunDuration; 111 } 112 } 113 114 public void retrieveUiData(Context context, PackageManager pm) { 115 mUiTargetApp = null; 116 mUiLabel = mPackage; 117 // Only one app associated with this process. 118 try { 119 if ("os".equals(mPackage)) { 120 mUiTargetApp = pm.getApplicationInfo("android", 121 PackageManager.GET_DISABLED_COMPONENTS | 122 PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS | 123 PackageManager.GET_UNINSTALLED_PACKAGES); 124 mUiLabel = context.getString(R.string.process_stats_os_label); 125 } else { 126 mUiTargetApp = pm.getApplicationInfo(mPackage, 127 PackageManager.GET_DISABLED_COMPONENTS | 128 PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS | 129 PackageManager.GET_UNINSTALLED_PACKAGES); 130 mUiLabel = mUiTargetApp.loadLabel(pm).toString(); 131 } 132 } catch (PackageManager.NameNotFoundException e) { 133 } 134 } 135 136 @Override 137 public int describeContents() { 138 return 0; 139 } 140 141 @Override 142 public void writeToParcel(Parcel dest, int flags) { 143 dest.writeString(mPackage); 144 dest.writeTypedList(mEntries); 145 dest.writeLong(mBgDuration); 146 dest.writeLong(mAvgBgMem); 147 dest.writeLong(mMaxBgMem); 148 dest.writeDouble(mBgWeight); 149 dest.writeLong(mRunDuration); 150 dest.writeLong(mAvgRunMem); 151 dest.writeLong(mMaxRunMem); 152 dest.writeDouble(mRunWeight); 153 } 154 155 public static final Parcelable.Creator<ProcStatsPackageEntry> CREATOR 156 = new Parcelable.Creator<ProcStatsPackageEntry>() { 157 public ProcStatsPackageEntry createFromParcel(Parcel in) { 158 return new ProcStatsPackageEntry(in); 159 } 160 161 public ProcStatsPackageEntry[] newArray(int size) { 162 return new ProcStatsPackageEntry[size]; 163 } 164 }; 165 166 // TODO: Find better place for this. 167 public static CharSequence getFrequency(float amount, Context context) { 168 if (amount> ALWAYS_THRESHOLD) { 169 return context.getString(R.string.always_running); 170 } else if (amount> SOMETIMES_THRESHOLD) { 171 return context.getString(R.string.sometimes_running); 172 } else { 173 return context.getString(R.string.rarely_running); 174 } 175 } 176} 177