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