104486738342fa5e11a78df836efe34b85bee125aDianne Hackborn/*
204486738342fa5e11a78df836efe34b85bee125aDianne Hackborn * Copyright (C) 2013 The Android Open Source Project
304486738342fa5e11a78df836efe34b85bee125aDianne Hackborn *
404486738342fa5e11a78df836efe34b85bee125aDianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
504486738342fa5e11a78df836efe34b85bee125aDianne Hackborn * you may not use this file except in compliance with the License.
604486738342fa5e11a78df836efe34b85bee125aDianne Hackborn * You may obtain a copy of the License at
704486738342fa5e11a78df836efe34b85bee125aDianne Hackborn *
804486738342fa5e11a78df836efe34b85bee125aDianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
904486738342fa5e11a78df836efe34b85bee125aDianne Hackborn *
1004486738342fa5e11a78df836efe34b85bee125aDianne Hackborn * Unless required by applicable law or agreed to in writing, software
1104486738342fa5e11a78df836efe34b85bee125aDianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
1204486738342fa5e11a78df836efe34b85bee125aDianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1304486738342fa5e11a78df836efe34b85bee125aDianne Hackborn * See the License for the specific language governing permissions and
1404486738342fa5e11a78df836efe34b85bee125aDianne Hackborn * limitations under the License.
1504486738342fa5e11a78df836efe34b85bee125aDianne Hackborn */
1604486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
1704486738342fa5e11a78df836efe34b85bee125aDianne Hackbornpackage com.android.settings.applications;
1804486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
1904486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport android.app.Activity;
2004486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport android.app.ActivityManager;
2104486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport android.app.Fragment;
2204486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport android.app.admin.DevicePolicyManager;
2304486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport android.content.BroadcastReceiver;
2404486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport android.content.Context;
2504486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport android.content.Intent;
2604486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport android.content.pm.ApplicationInfo;
2704486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport android.content.pm.PackageManager;
2804486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport android.content.res.Resources;
2904486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport android.net.Uri;
3004486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport android.os.Bundle;
3104486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport android.os.Process;
32235e5d686fc73cfd82605bac86dcc9673916c5b7Christopher Tateimport android.os.UserHandle;
3304486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport android.text.format.Formatter;
3404486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport android.view.LayoutInflater;
3504486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport android.view.View;
3604486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport android.view.ViewGroup;
3704486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport android.widget.Button;
3804486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport android.widget.ImageView;
3904486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport android.widget.ProgressBar;
4004486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport android.widget.TextView;
4104486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport com.android.settings.R;
427253df35a09d8d61ececedbb66179171802e42a7Elliott Hughesimport com.android.settings.Utils;
4304486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
4404486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport java.util.ArrayList;
4504486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport java.util.Collections;
4604486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport java.util.Comparator;
4704486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
4804486738342fa5e11a78df836efe34b85bee125aDianne Hackbornimport static com.android.settings.Utils.prepareCustomPreferencesList;
4904486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
5004486738342fa5e11a78df836efe34b85bee125aDianne Hackbornpublic class ProcessStatsDetail extends Fragment implements Button.OnClickListener {
5104486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    private static final String TAG = "ProcessStatsDetail";
5204486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
5304486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    public static final int ACTION_FORCE_STOP = 1;
5404486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
5504486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    public static final String EXTRA_ENTRY = "entry";
5649759af6b06b884d3a1af9dbb120370893744b94Dianne Hackborn    public static final String EXTRA_USE_USS = "use_uss";
5704486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    public static final String EXTRA_MAX_WEIGHT = "max_weight";
5804486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    public static final String EXTRA_TOTAL_TIME = "total_time";
5904486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
6004486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    private PackageManager mPm;
6104486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    private DevicePolicyManager mDpm;
6204486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
6304486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    private ProcStatsEntry mEntry;
6449759af6b06b884d3a1af9dbb120370893744b94Dianne Hackborn    private boolean mUseUss;
6504486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    private long mMaxWeight;
6604486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    private long mTotalTime;
6704486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
6804486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    private View mRootView;
6904486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    private TextView mTitleView;
7004486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    private ViewGroup mTwoButtonsPanel;
7104486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    private Button mForceStopButton;
7204486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    private Button mReportButton;
7304486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    private ViewGroup mDetailsParent;
7404486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    private ViewGroup mServicesParent;
7504486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
7604486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    @Override
7704486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    public void onCreate(Bundle icicle) {
7804486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        super.onCreate(icicle);
7904486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        mPm = getActivity().getPackageManager();
8004486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        mDpm = (DevicePolicyManager)getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);
8104486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        final Bundle args = getArguments();
8204486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        mEntry = (ProcStatsEntry)args.getParcelable(EXTRA_ENTRY);
8304486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        mEntry.retrieveUiData(mPm);
8449759af6b06b884d3a1af9dbb120370893744b94Dianne Hackborn        mUseUss = args.getBoolean(EXTRA_USE_USS);
8504486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        mMaxWeight = args.getLong(EXTRA_MAX_WEIGHT);
8604486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        mTotalTime = args.getLong(EXTRA_TOTAL_TIME);
8704486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    }
8804486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
8904486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    @Override
9004486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    public View onCreateView(
9104486738342fa5e11a78df836efe34b85bee125aDianne Hackborn            LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
9204486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        final View view = inflater.inflate(R.layout.process_stats_details, container, false);
9304486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        prepareCustomPreferencesList(container, view, view, false);
9404486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
9504486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        mRootView = view;
9604486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        createDetails();
9704486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        return view;
9804486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    }
9904486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
10004486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    @Override
10104486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    public void onResume() {
10204486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        super.onResume();
10304486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        checkForceStop();
10404486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    }
10504486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
10604486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    @Override
10704486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    public void onPause() {
10804486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        super.onPause();
10904486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    }
11004486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
11104486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    private void createDetails() {
11204486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        final double percentOfWeight = (((double)mEntry.mWeight) / mMaxWeight) * 100;
11304486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
11404486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        int appLevel = (int) Math.ceil(percentOfWeight);
1157253df35a09d8d61ececedbb66179171802e42a7Elliott Hughes        String appLevelText = Utils.formatPercentage(mEntry.mDuration, mTotalTime);
11604486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
11704486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        // Set all values in the header.
11804486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        final TextView summary = (TextView) mRootView.findViewById(android.R.id.summary);
11904486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        summary.setText(mEntry.mName);
12004486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        summary.setVisibility(View.VISIBLE);
12104486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        mTitleView = (TextView) mRootView.findViewById(android.R.id.title);
12204486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        mTitleView.setText(mEntry.mUiBaseLabel);
12304486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        final TextView text1 = (TextView)mRootView.findViewById(android.R.id.text1);
12404486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        text1.setText(appLevelText);
12504486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        final ProgressBar progress = (ProgressBar) mRootView.findViewById(android.R.id.progress);
12604486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        progress.setProgress(appLevel);
12704486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        final ImageView icon = (ImageView) mRootView.findViewById(android.R.id.icon);
12804486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        if (mEntry.mUiTargetApp != null) {
12904486738342fa5e11a78df836efe34b85bee125aDianne Hackborn            icon.setImageDrawable(mEntry.mUiTargetApp.loadIcon(mPm));
13004486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        }
13104486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
13204486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        mTwoButtonsPanel = (ViewGroup)mRootView.findViewById(R.id.two_buttons_panel);
13304486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        mForceStopButton = (Button)mRootView.findViewById(R.id.right_button);
13404486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        mReportButton = (Button)mRootView.findViewById(R.id.left_button);
13504486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        mForceStopButton.setEnabled(false);
13604486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        mReportButton.setVisibility(View.INVISIBLE);
13704486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
13804486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        mDetailsParent = (ViewGroup)mRootView.findViewById(R.id.details);
13904486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        mServicesParent = (ViewGroup)mRootView.findViewById(R.id.services);
14004486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
14104486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        fillDetailsSection();
14204486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        fillServicesSection();
14304486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
14404486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        if (mEntry.mUid >= android.os.Process.FIRST_APPLICATION_UID) {
14504486738342fa5e11a78df836efe34b85bee125aDianne Hackborn            mForceStopButton.setText(R.string.force_stop);
14604486738342fa5e11a78df836efe34b85bee125aDianne Hackborn            mForceStopButton.setTag(ACTION_FORCE_STOP);
14704486738342fa5e11a78df836efe34b85bee125aDianne Hackborn            mForceStopButton.setOnClickListener(this);
14804486738342fa5e11a78df836efe34b85bee125aDianne Hackborn            mTwoButtonsPanel.setVisibility(View.VISIBLE);
14904486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        } else {
15004486738342fa5e11a78df836efe34b85bee125aDianne Hackborn            mTwoButtonsPanel.setVisibility(View.GONE);
15104486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        }
15204486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    }
15304486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
15404486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    public void onClick(View v) {
15504486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        doAction((Integer) v.getTag());
15604486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    }
15704486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
15804486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    private void doAction(int action) {
15904486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        switch (action) {
16004486738342fa5e11a78df836efe34b85bee125aDianne Hackborn            case ACTION_FORCE_STOP:
16104486738342fa5e11a78df836efe34b85bee125aDianne Hackborn                killProcesses();
16204486738342fa5e11a78df836efe34b85bee125aDianne Hackborn                break;
16304486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        }
16404486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    }
16504486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
1665635594c38fb319e050054e42109eb736f274accDianne Hackborn    private void addPackageHeaderItem(ViewGroup parent, String packageName) {
1675635594c38fb319e050054e42109eb736f274accDianne Hackborn        LayoutInflater inflater = getActivity().getLayoutInflater();
1685635594c38fb319e050054e42109eb736f274accDianne Hackborn        ViewGroup item = (ViewGroup) inflater.inflate(R.layout.running_processes_item,
1695635594c38fb319e050054e42109eb736f274accDianne Hackborn                null);
1705635594c38fb319e050054e42109eb736f274accDianne Hackborn        parent.addView(item);
1715635594c38fb319e050054e42109eb736f274accDianne Hackborn        final ImageView icon = (ImageView) item.findViewById(R.id.icon);
1725635594c38fb319e050054e42109eb736f274accDianne Hackborn        TextView nameView = (TextView) item.findViewById(R.id.name);
1735635594c38fb319e050054e42109eb736f274accDianne Hackborn        TextView descriptionView = (TextView) item.findViewById(R.id.description);
1745635594c38fb319e050054e42109eb736f274accDianne Hackborn        try {
1755635594c38fb319e050054e42109eb736f274accDianne Hackborn            ApplicationInfo ai = mPm.getApplicationInfo(packageName, 0);
1765635594c38fb319e050054e42109eb736f274accDianne Hackborn            icon.setImageDrawable(ai.loadIcon(mPm));
1775635594c38fb319e050054e42109eb736f274accDianne Hackborn            nameView.setText(ai.loadLabel(mPm));
1785635594c38fb319e050054e42109eb736f274accDianne Hackborn        } catch (PackageManager.NameNotFoundException e) {
1795635594c38fb319e050054e42109eb736f274accDianne Hackborn        }
1805635594c38fb319e050054e42109eb736f274accDianne Hackborn        descriptionView.setText(packageName);
1815635594c38fb319e050054e42109eb736f274accDianne Hackborn    }
1825635594c38fb319e050054e42109eb736f274accDianne Hackborn
18304486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    private void addDetailsItem(ViewGroup parent, CharSequence label, CharSequence value) {
18404486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        LayoutInflater inflater = getActivity().getLayoutInflater();
18504486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        ViewGroup item = (ViewGroup) inflater.inflate(R.layout.power_usage_detail_item_text,
18604486738342fa5e11a78df836efe34b85bee125aDianne Hackborn                null);
18704486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        parent.addView(item);
18804486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        TextView labelView = (TextView) item.findViewById(R.id.label);
18904486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        TextView valueView = (TextView) item.findViewById(R.id.value);
19004486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        labelView.setText(label);
19104486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        valueView.setText(value);
19204486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    }
19304486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
19404486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    private void fillDetailsSection() {
19549759af6b06b884d3a1af9dbb120370893744b94Dianne Hackborn        addDetailsItem(mDetailsParent, getResources().getText(R.string.process_stats_avg_ram_use),
19649759af6b06b884d3a1af9dbb120370893744b94Dianne Hackborn                Formatter.formatShortFileSize(getActivity(),
19749759af6b06b884d3a1af9dbb120370893744b94Dianne Hackborn                        (mUseUss ? mEntry.mAvgUss : mEntry.mAvgPss) * 1024));
19849759af6b06b884d3a1af9dbb120370893744b94Dianne Hackborn        addDetailsItem(mDetailsParent, getResources().getText(R.string.process_stats_max_ram_use),
19949759af6b06b884d3a1af9dbb120370893744b94Dianne Hackborn                Formatter.formatShortFileSize(getActivity(),
20049759af6b06b884d3a1af9dbb120370893744b94Dianne Hackborn                        (mUseUss ? mEntry.mMaxUss : mEntry.mMaxPss) * 1024));
20104486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        addDetailsItem(mDetailsParent, getResources().getText(R.string.process_stats_run_time),
2027253df35a09d8d61ececedbb66179171802e42a7Elliott Hughes                Utils.formatPercentage(mEntry.mDuration, mTotalTime));
20304486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    }
20404486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
20504486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    final static Comparator<ProcStatsEntry.Service> sServiceCompare
20604486738342fa5e11a78df836efe34b85bee125aDianne Hackborn            = new Comparator<ProcStatsEntry.Service>() {
20704486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        @Override
20804486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        public int compare(ProcStatsEntry.Service lhs, ProcStatsEntry.Service rhs) {
20904486738342fa5e11a78df836efe34b85bee125aDianne Hackborn            if (lhs.mDuration < rhs.mDuration) {
21004486738342fa5e11a78df836efe34b85bee125aDianne Hackborn                return 1;
21104486738342fa5e11a78df836efe34b85bee125aDianne Hackborn            } else if (lhs.mDuration > rhs.mDuration) {
21204486738342fa5e11a78df836efe34b85bee125aDianne Hackborn                return -1;
21304486738342fa5e11a78df836efe34b85bee125aDianne Hackborn            }
21404486738342fa5e11a78df836efe34b85bee125aDianne Hackborn            return 0;
21504486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        }
21604486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    };
21704486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
218020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn    final static Comparator<ArrayList<ProcStatsEntry.Service>> sServicePkgCompare
219020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn            = new Comparator<ArrayList<ProcStatsEntry.Service>>() {
220020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn        @Override
221020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn        public int compare(ArrayList<ProcStatsEntry.Service> lhs,
222020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn                ArrayList<ProcStatsEntry.Service> rhs) {
223020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn            long topLhs = lhs.size() > 0 ? lhs.get(0).mDuration : 0;
224020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn            long topRhs = rhs.size() > 0 ? rhs.get(0).mDuration : 0;
225020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn            if (topLhs < topRhs) {
226020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn                return 1;
227020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn            } else if (topLhs > topRhs) {
228020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn                return -1;
229020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn            }
230020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn            return 0;
231020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn        }
232020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn    };
233020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn
23404486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    private void fillServicesSection() {
23504486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        if (mEntry.mServices.size() > 0) {
2365635594c38fb319e050054e42109eb736f274accDianne Hackborn            boolean addPackageSections = false;
237020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn            // Sort it all.
238020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn            ArrayList<ArrayList<ProcStatsEntry.Service>> servicePkgs
239020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn                    = new ArrayList<ArrayList<ProcStatsEntry.Service>>();
2405635594c38fb319e050054e42109eb736f274accDianne Hackborn            for (int ip=0; ip<mEntry.mServices.size(); ip++) {
2415635594c38fb319e050054e42109eb736f274accDianne Hackborn                ArrayList<ProcStatsEntry.Service> services =
2425635594c38fb319e050054e42109eb736f274accDianne Hackborn                        (ArrayList<ProcStatsEntry.Service>)mEntry.mServices.valueAt(ip).clone();
2435635594c38fb319e050054e42109eb736f274accDianne Hackborn                Collections.sort(services, sServiceCompare);
244020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn                servicePkgs.add(services);
245020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn            }
246020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn            if (mEntry.mServices.size() > 1
247020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn                    || !mEntry.mServices.valueAt(0).get(0).mPackage.equals(mEntry.mPackage)) {
248020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn                addPackageSections = true;
249020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn                // Sort these so that the one(s) with the longest run durations are on top.
250020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn                Collections.sort(servicePkgs, sServicePkgCompare);
251020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn            }
252020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn            for (int ip=0; ip<servicePkgs.size(); ip++) {
253020999103b34860a89576cd5dba862009337e9a9Dianne Hackborn                ArrayList<ProcStatsEntry.Service> services = servicePkgs.get(ip);
2545635594c38fb319e050054e42109eb736f274accDianne Hackborn                if (addPackageSections) {
2555635594c38fb319e050054e42109eb736f274accDianne Hackborn                    addPackageHeaderItem(mServicesParent, services.get(0).mPackage);
2565635594c38fb319e050054e42109eb736f274accDianne Hackborn                }
2575635594c38fb319e050054e42109eb736f274accDianne Hackborn                for (int is=0; is<services.size(); is++) {
2585635594c38fb319e050054e42109eb736f274accDianne Hackborn                    ProcStatsEntry.Service service = services.get(is);
2595635594c38fb319e050054e42109eb736f274accDianne Hackborn                    String label = service.mName;
2605635594c38fb319e050054e42109eb736f274accDianne Hackborn                    int tail = label.lastIndexOf('.');
2615635594c38fb319e050054e42109eb736f274accDianne Hackborn                    if (tail >= 0 && tail < (label.length()-1)) {
2625635594c38fb319e050054e42109eb736f274accDianne Hackborn                        label = label.substring(tail+1);
2635635594c38fb319e050054e42109eb736f274accDianne Hackborn                    }
2647253df35a09d8d61ececedbb66179171802e42a7Elliott Hughes                    String percentage = Utils.formatPercentage(service.mDuration, mTotalTime);
2657253df35a09d8d61ececedbb66179171802e42a7Elliott Hughes                    addDetailsItem(mServicesParent, label, percentage);
26604486738342fa5e11a78df836efe34b85bee125aDianne Hackborn                }
26704486738342fa5e11a78df836efe34b85bee125aDianne Hackborn            }
26804486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        }
26904486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    }
27004486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
27104486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    private void killProcesses() {
27204486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        ActivityManager am = (ActivityManager)getActivity().getSystemService(
27304486738342fa5e11a78df836efe34b85bee125aDianne Hackborn                Context.ACTIVITY_SERVICE);
27404486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        am.forceStopPackage(mEntry.mUiPackage);
27504486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        checkForceStop();
27604486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    }
27704486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
27804486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    private final BroadcastReceiver mCheckKillProcessesReceiver = new BroadcastReceiver() {
27904486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        @Override
28004486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        public void onReceive(Context context, Intent intent) {
28104486738342fa5e11a78df836efe34b85bee125aDianne Hackborn            mForceStopButton.setEnabled(getResultCode() != Activity.RESULT_CANCELED);
28204486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        }
28304486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    };
28404486738342fa5e11a78df836efe34b85bee125aDianne Hackborn
28504486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    private void checkForceStop() {
28604486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        if (mEntry.mUiPackage == null || mEntry.mUid < Process.FIRST_APPLICATION_UID) {
28704486738342fa5e11a78df836efe34b85bee125aDianne Hackborn            mForceStopButton.setEnabled(false);
28804486738342fa5e11a78df836efe34b85bee125aDianne Hackborn            return;
28904486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        }
29004486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        if (mDpm.packageHasActiveAdmins(mEntry.mUiPackage)) {
29104486738342fa5e11a78df836efe34b85bee125aDianne Hackborn            mForceStopButton.setEnabled(false);
29204486738342fa5e11a78df836efe34b85bee125aDianne Hackborn            return;
29304486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        }
29404486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        try {
29504486738342fa5e11a78df836efe34b85bee125aDianne Hackborn            ApplicationInfo info = mPm.getApplicationInfo(mEntry.mUiPackage, 0);
29604486738342fa5e11a78df836efe34b85bee125aDianne Hackborn            if ((info.flags&ApplicationInfo.FLAG_STOPPED) == 0) {
29704486738342fa5e11a78df836efe34b85bee125aDianne Hackborn                mForceStopButton.setEnabled(true);
29804486738342fa5e11a78df836efe34b85bee125aDianne Hackborn            }
29904486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        } catch (PackageManager.NameNotFoundException e) {
30004486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        }
30104486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART,
30204486738342fa5e11a78df836efe34b85bee125aDianne Hackborn                Uri.fromParts("package", mEntry.mUiPackage, null));
30304486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        intent.putExtra(Intent.EXTRA_PACKAGES, new String[] { mEntry.mUiPackage });
30404486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        intent.putExtra(Intent.EXTRA_UID, mEntry.mUid);
305235e5d686fc73cfd82605bac86dcc9673916c5b7Christopher Tate        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(mEntry.mUid));
30604486738342fa5e11a78df836efe34b85bee125aDianne Hackborn        getActivity().sendOrderedBroadcast(intent, null, mCheckKillProcessesReceiver, null,
30704486738342fa5e11a78df836efe34b85bee125aDianne Hackborn                Activity.RESULT_CANCELED, null, null);
30804486738342fa5e11a78df836efe34b85bee125aDianne Hackborn    }
30904486738342fa5e11a78df836efe34b85bee125aDianne Hackborn}
310