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 package com.android.settings.applications; 17 18 import android.app.settings.SettingsEnums; 19 import android.content.ContentResolver; 20 import android.content.Context; 21 import android.icu.text.MessageFormat; 22 import android.os.Bundle; 23 import android.os.Flags; 24 import android.provider.Settings; 25 import android.text.format.Formatter; 26 import android.text.format.Formatter.BytesResult; 27 28 import androidx.preference.Preference; 29 import androidx.preference.Preference.OnPreferenceClickListener; 30 import androidx.preference.PreferenceCategory; 31 import androidx.preference.SwitchPreference; 32 33 import com.android.settings.R; 34 import com.android.settings.SummaryPreference; 35 import com.android.settings.Utils; 36 import com.android.settings.applications.ProcStatsData.MemInfo; 37 import com.android.settings.core.SubSettingLauncher; 38 import com.android.settings.development.DeveloperOptionAwareMixin; 39 import com.android.settings.development.DisableDevSettingsDialogFragment; 40 41 import java.util.HashMap; 42 import java.util.Locale; 43 import java.util.Map; 44 45 public class ProcessStatsSummary extends ProcessStatsBase implements OnPreferenceClickListener, 46 DeveloperOptionAwareMixin { 47 48 private static final String KEY_PREF_SCREEN = "app_list"; 49 private static final String KEY_MEMORY_INFO_PREF_GROUP = "memory_info"; 50 private static final String KEY_STATUS_HEADER = "status_header"; 51 52 private static final String KEY_PERFORMANCE = "performance"; 53 private static final String KEY_TOTAL_MEMORY = "total_memory"; 54 private static final String KEY_AVERAGY_USED = "average_used"; 55 private static final String KEY_FREE = "free"; 56 private static final String KEY_APP_LIST = "apps_list"; 57 private static final String KEY_FORCE_ENABLE_PSS_PROFILING = "force_enable_pss_profiling"; 58 59 private PreferenceCategory mMemoryInfoPrefCategory; 60 private SummaryPreference mSummaryPref; 61 62 private Preference mPerformance; 63 private Preference mTotalMemory; 64 private Preference mAverageUsed; 65 private Preference mFree; 66 private Preference mAppListPreference; 67 private SwitchPreference mForceEnablePssProfiling; 68 69 @Override onCreate(Bundle icicle)70 public void onCreate(Bundle icicle) { 71 super.onCreate(icicle); 72 73 addPreferencesFromResource(R.xml.process_stats_summary); 74 mMemoryInfoPrefCategory = (PreferenceCategory) findPreference(KEY_MEMORY_INFO_PREF_GROUP); 75 mSummaryPref = (SummaryPreference) findPreference(KEY_STATUS_HEADER); 76 mPerformance = findPreference(KEY_PERFORMANCE); 77 mTotalMemory = findPreference(KEY_TOTAL_MEMORY); 78 mAverageUsed = findPreference(KEY_AVERAGY_USED); 79 mFree = findPreference(KEY_FREE); 80 mAppListPreference = findPreference(KEY_APP_LIST); 81 mAppListPreference.setOnPreferenceClickListener(this); 82 83 // This preference is only applicable if the flag for PSS deprecation in AppProfiler is 84 // enabled. Otherwise, it can immediately be hidden. 85 mForceEnablePssProfiling = 86 (SwitchPreference) findPreference(KEY_FORCE_ENABLE_PSS_PROFILING); 87 if (Flags.removeAppProfilerPssCollection()) { 88 mForceEnablePssProfiling.setOnPreferenceClickListener(this); 89 // Make the toggle reflect the current state of the global setting. 90 mForceEnablePssProfiling.setChecked(isPssProfilingForceEnabled(getContext())); 91 } else { 92 mForceEnablePssProfiling.setVisible(false); 93 } 94 } 95 refreshPreferences()96 private void refreshPreferences() { 97 // The memory fields should be static if the flag is not enabled. 98 if (!Flags.removeAppProfilerPssCollection()) { 99 return; 100 } 101 mMemoryInfoPrefCategory.setVisible(mForceEnablePssProfiling.isChecked()); 102 } 103 104 @Override refreshUi()105 public void refreshUi() { 106 Context context = getContext(); 107 refreshPreferences(); 108 109 // If PSS collection is not enabled, none of the following work needs to be done. 110 if (Flags.removeAppProfilerPssCollection() && !isPssProfilingForceEnabled(context)) { 111 return; 112 } 113 114 MemInfo memInfo = mStatsManager.getMemInfo(); 115 116 double usedRam = memInfo.realUsedRam; 117 double totalRam = memInfo.realTotalRam; 118 double freeRam = memInfo.realFreeRam; 119 BytesResult usedResult = Formatter.formatBytes(context.getResources(), (long) usedRam, 120 Formatter.FLAG_SHORTER); 121 String totalString = Formatter.formatShortFileSize(context, (long) totalRam); 122 String freeString = Formatter.formatShortFileSize(context, (long) freeRam); 123 CharSequence memString; 124 CharSequence[] memStatesStr = getResources().getTextArray(R.array.ram_states); 125 int memState = mStatsManager.getMemState(); 126 if (memState >= 0 && memState < memStatesStr.length - 1) { 127 memString = memStatesStr[memState]; 128 } else { 129 memString = memStatesStr[memStatesStr.length - 1]; 130 } 131 mSummaryPref.setAmount(usedResult.value); 132 mSummaryPref.setUnits(usedResult.units); 133 float usedRatio = (float)(usedRam / (freeRam + usedRam)); 134 mSummaryPref.setRatios(usedRatio, 0, 1 - usedRatio); 135 136 mPerformance.setSummary(memString); 137 mTotalMemory.setSummary(totalString); 138 mAverageUsed.setSummary(Utils.formatPercentage((long) usedRam, (long) totalRam)); 139 mFree.setSummary(freeString); 140 String durationString = getString(sDurationLabels[mDurationIndex]); 141 int numApps = mStatsManager.getEntries().size(); 142 MessageFormat msgFormat = new MessageFormat( 143 getResources().getString(R.string.memory_usage_apps_summary), 144 Locale.getDefault()); 145 Map<String, Object> arguments = new HashMap<>(); 146 arguments.put("count", numApps); 147 arguments.put("time", durationString); 148 mAppListPreference.setSummary(msgFormat.format(arguments)); 149 } 150 151 @Override getMetricsCategory()152 public int getMetricsCategory() { 153 return SettingsEnums.PROCESS_STATS_SUMMARY; 154 } 155 156 @Override getHelpResource()157 public int getHelpResource() { 158 return R.string.help_uri_process_stats_summary; 159 } 160 161 @Override onPreferenceClick(Preference preference)162 public boolean onPreferenceClick(Preference preference) { 163 if (preference == mAppListPreference) { 164 final Bundle args = new Bundle(); 165 args.putBoolean(ARG_TRANSFER_STATS, true); 166 args.putInt(ARG_DURATION_INDEX, mDurationIndex); 167 mStatsManager.xferStats(); 168 new SubSettingLauncher(getContext()) 169 .setDestination(ProcessStatsUi.class.getName()) 170 .setTitleRes(R.string.memory_usage_apps) 171 .setArguments(args) 172 .setSourceMetricsCategory(getMetricsCategory()) 173 .launch(); 174 return true; 175 } else if (preference == mForceEnablePssProfiling) { 176 DisableDevSettingsDialogFragment.show(this); 177 } 178 return false; 179 } 180 isPssProfilingForceEnabled(Context context)181 private boolean isPssProfilingForceEnabled(Context context) { 182 ContentResolver cr = context.getContentResolver(); 183 return Settings.Global.getInt(cr, Settings.Global.FORCE_ENABLE_PSS_PROFILING, 0) == 1; 184 } 185 186 /** 187 * Called when the reboot confirmation button is clicked. 188 */ onRebootDialogConfirmed()189 public void onRebootDialogConfirmed() { 190 Context context = getContext(); 191 ContentResolver cr = context.getContentResolver(); 192 Settings.Global.putInt(cr, Settings.Global.FORCE_ENABLE_PSS_PROFILING, 193 mForceEnablePssProfiling.isChecked() ? 1 : 0); 194 refreshPreferences(); 195 } 196 197 /** 198 * Called when the reboot deny button is clicked. 199 */ onRebootDialogCanceled()200 public void onRebootDialogCanceled() { 201 // Set the toggle to reflect the state of the setting, which should not have changed. 202 mForceEnablePssProfiling.setChecked(isPssProfilingForceEnabled(getContext())); 203 } 204 205 } 206