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.os.Bundle; 19 import android.view.View; 20 import android.view.ViewGroup; 21 import android.widget.AdapterView; 22 import android.widget.AdapterView.OnItemSelectedListener; 23 import android.widget.ArrayAdapter; 24 import android.widget.Spinner; 25 26 import com.android.internal.app.procstats.ProcessStats; 27 import com.android.settings.R; 28 import com.android.settings.SettingsActivity; 29 import com.android.settings.SettingsPreferenceFragment; 30 import com.android.settings.applications.ProcStatsData.MemInfo; 31 import com.android.settings.core.SubSettingLauncher; 32 import com.android.settingslib.core.instrumentation.Instrumentable; 33 import com.android.settingslib.widget.settingsspinner.SettingsSpinnerAdapter; 34 35 public abstract class ProcessStatsBase extends SettingsPreferenceFragment 36 implements OnItemSelectedListener { 37 private static final String DURATION = "duration"; 38 39 protected static final String ARG_TRANSFER_STATS = "transfer_stats"; 40 protected static final String ARG_DURATION_INDEX = "duration_index"; 41 42 protected static final int NUM_DURATIONS = 4; 43 44 // The actual duration value to use for each duration option. Note these 45 // are lower than the actual duration, since our durations are computed in 46 // batches of 3 hours so we want to allow the time we use to be slightly 47 // smaller than the actual time selected instead of bumping up to 3 hours 48 // beyond it. 49 private static final long DURATION_QUANTUM = ProcessStats.COMMIT_PERIOD; 50 public static long[] sDurations = new long[] { 51 3 * 60 * 60 * 1000 - DURATION_QUANTUM / 2, 6 * 60 * 60 * 1000 - DURATION_QUANTUM / 2, 52 12 * 60 * 60 * 1000 - DURATION_QUANTUM / 2, 24 * 60 * 60 * 1000 - DURATION_QUANTUM / 2 53 }; 54 protected static int[] sDurationLabels = new int[] { 55 R.string.menu_duration_3h, R.string.menu_duration_6h, 56 R.string.menu_duration_12h, R.string.menu_duration_1d 57 }; 58 59 private ViewGroup mSpinnerHeader; 60 private Spinner mFilterSpinner; 61 private ArrayAdapter<String> mFilterAdapter; 62 63 protected ProcStatsData mStatsManager; 64 protected int mDurationIndex; 65 66 @Override onCreate(Bundle icicle)67 public void onCreate(Bundle icicle) { 68 super.onCreate(icicle); 69 70 Bundle args = getArguments(); 71 mStatsManager = new ProcStatsData(getActivity(), icicle != null 72 || (args != null && args.getBoolean(ARG_TRANSFER_STATS, false))); 73 74 mDurationIndex = icicle != null 75 ? icicle.getInt(ARG_DURATION_INDEX) 76 : args != null ? args.getInt(ARG_DURATION_INDEX) : 0; 77 mStatsManager.setDuration(icicle != null 78 ? icicle.getLong(DURATION, sDurations[0]) : sDurations[0]); 79 } 80 81 @Override onSaveInstanceState(Bundle outState)82 public void onSaveInstanceState(Bundle outState) { 83 super.onSaveInstanceState(outState); 84 outState.putLong(DURATION, mStatsManager.getDuration()); 85 outState.putInt(ARG_DURATION_INDEX, mDurationIndex); 86 } 87 88 @Override onResume()89 public void onResume() { 90 super.onResume(); 91 mStatsManager.refreshStats(false); 92 refreshUi(); 93 } 94 95 @Override onDestroy()96 public void onDestroy() { 97 super.onDestroy(); 98 if (getActivity().isChangingConfigurations()) { 99 mStatsManager.xferStats(); 100 } 101 } 102 103 @Override onViewCreated(View view, Bundle savedInstanceState)104 public void onViewCreated(View view, Bundle savedInstanceState) { 105 super.onViewCreated(view, savedInstanceState); 106 mSpinnerHeader = (ViewGroup) setPinnedHeaderView(R.layout.apps_filter_spinner); 107 mFilterSpinner = (Spinner) mSpinnerHeader.findViewById(R.id.filter_spinner); 108 mFilterAdapter = new SettingsSpinnerAdapter<String>(mFilterSpinner.getContext()); 109 110 for (int i = 0; i < NUM_DURATIONS; i++) { 111 mFilterAdapter.add(getString(sDurationLabels[i])); 112 } 113 mFilterSpinner.setAdapter(mFilterAdapter); 114 mFilterSpinner.setSelection(mDurationIndex); 115 mFilterSpinner.setOnItemSelectedListener(this); 116 } 117 118 @Override onItemSelected(AdapterView<?> parent, View view, int position, long id)119 public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 120 mDurationIndex = position; 121 mStatsManager.setDuration(sDurations[position]); 122 refreshUi(); 123 } 124 125 @Override onNothingSelected(AdapterView<?> parent)126 public void onNothingSelected(AdapterView<?> parent) { 127 // Select something. 128 mFilterSpinner.setSelection(0); 129 } 130 refreshUi()131 public abstract void refreshUi(); 132 launchMemoryDetail(SettingsActivity activity, MemInfo memInfo, ProcStatsPackageEntry entry, boolean includeAppInfo)133 public static void launchMemoryDetail(SettingsActivity activity, MemInfo memInfo, 134 ProcStatsPackageEntry entry, boolean includeAppInfo) { 135 Bundle args = new Bundle(); 136 args.putParcelable(ProcessStatsDetail.EXTRA_PACKAGE_ENTRY, entry); 137 args.putDouble(ProcessStatsDetail.EXTRA_WEIGHT_TO_RAM, memInfo.weightToRam); 138 args.putLong(ProcessStatsDetail.EXTRA_TOTAL_TIME, memInfo.memTotalTime); 139 args.putDouble(ProcessStatsDetail.EXTRA_MAX_MEMORY_USAGE, 140 memInfo.usedWeight * memInfo.weightToRam); 141 args.putDouble(ProcessStatsDetail.EXTRA_TOTAL_SCALE, memInfo.totalScale); 142 new SubSettingLauncher(activity) 143 .setDestination(ProcessStatsDetail.class.getName()) 144 .setTitleRes(R.string.memory_usage) 145 .setArguments(args) 146 .setSourceMetricsCategory(Instrumentable.METRICS_CATEGORY_UNKNOWN) 147 .launch(); 148 } 149 } 150