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 34 public abstract class ProcessStatsBase extends SettingsPreferenceFragment 35 implements OnItemSelectedListener { 36 private static final String DURATION = "duration"; 37 38 protected static final String ARG_TRANSFER_STATS = "transfer_stats"; 39 protected static final String ARG_DURATION_INDEX = "duration_index"; 40 41 protected static final int NUM_DURATIONS = 4; 42 43 // The actual duration value to use for each duration option. Note these 44 // are lower than the actual duration, since our durations are computed in 45 // batches of 3 hours so we want to allow the time we use to be slightly 46 // smaller than the actual time selected instead of bumping up to 3 hours 47 // beyond it. 48 private static final long DURATION_QUANTUM = ProcessStats.COMMIT_PERIOD; 49 public static long[] sDurations = new long[] { 50 3 * 60 * 60 * 1000 - DURATION_QUANTUM / 2, 6 * 60 * 60 * 1000 - DURATION_QUANTUM / 2, 51 12 * 60 * 60 * 1000 - DURATION_QUANTUM / 2, 24 * 60 * 60 * 1000 - DURATION_QUANTUM / 2 52 }; 53 protected static int[] sDurationLabels = new int[] { 54 R.string.menu_duration_3h, R.string.menu_duration_6h, 55 R.string.menu_duration_12h, R.string.menu_duration_1d 56 }; 57 58 private ViewGroup mSpinnerHeader; 59 private Spinner mFilterSpinner; 60 private ArrayAdapter<String> mFilterAdapter; 61 62 protected ProcStatsData mStatsManager; 63 protected int mDurationIndex; 64 65 @Override 66 public void onCreate(Bundle icicle) { 67 super.onCreate(icicle); 68 69 Bundle args = getArguments(); 70 mStatsManager = new ProcStatsData(getActivity(), icicle != null 71 || (args != null && args.getBoolean(ARG_TRANSFER_STATS, false))); 72 73 mDurationIndex = icicle != null 74 ? icicle.getInt(ARG_DURATION_INDEX) 75 : args != null ? args.getInt(ARG_DURATION_INDEX) : 0; 76 mStatsManager.setDuration(icicle != null 77 ? icicle.getLong(DURATION, sDurations[0]) : sDurations[0]); 78 } 79 80 @Override 81 public void onSaveInstanceState(Bundle outState) { 82 super.onSaveInstanceState(outState); 83 outState.putLong(DURATION, mStatsManager.getDuration()); 84 outState.putInt(ARG_DURATION_INDEX, mDurationIndex); 85 } 86 87 @Override 88 public void onResume() { 89 super.onResume(); 90 mStatsManager.refreshStats(false); 91 refreshUi(); 92 } 93 94 @Override 95 public void onDestroy() { 96 super.onDestroy(); 97 if (getActivity().isChangingConfigurations()) { 98 mStatsManager.xferStats(); 99 } 100 } 101 102 @Override 103 public void onViewCreated(View view, Bundle savedInstanceState) { 104 super.onViewCreated(view, savedInstanceState); 105 mSpinnerHeader = (ViewGroup) setPinnedHeaderView(R.layout.apps_filter_spinner); 106 mFilterSpinner = (Spinner) mSpinnerHeader.findViewById(R.id.filter_spinner); 107 mFilterAdapter = new ArrayAdapter<String>(mFilterSpinner.getContext(), 108 R.layout.filter_spinner_item); 109 mFilterAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 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 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 126 public void onNothingSelected(AdapterView<?> parent) { 127 // Select something. 128 mFilterSpinner.setSelection(0); 129 } 130 131 public abstract void refreshUi(); 132 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 .setTitle(R.string.memory_usage) 145 .setArguments(args) 146 .setSourceMetricsCategory(Instrumentable.METRICS_CATEGORY_UNKNOWN) 147 .launch(); 148 } 149 } 150