1e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski/*
2e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski * Copyright (C) 2014 The Android Open Source Project
3e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski *
4e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
5e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski * you may not use this file except in compliance with the License.
6e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski * You may obtain a copy of the License at
7e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski *
8e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
9e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski *
10e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski * Unless required by applicable law or agreed to in writing, software
11e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
12e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski * See the License for the specific language governing permissions and
14e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski * limitations under the License.
15e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski */
16e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski
17e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinskipackage com.android.tests.usagestats;
18e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski
19e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinskiimport android.app.ListActivity;
20e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinskiimport android.app.usage.UsageStats;
21e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinskiimport android.app.usage.UsageStatsManager;
22e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinskiimport android.content.Context;
233516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport android.content.Intent;
24e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinskiimport android.os.Bundle;
25e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinskiimport android.text.format.DateUtils;
26e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinskiimport android.view.LayoutInflater;
273516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport android.view.Menu;
283516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport android.view.MenuInflater;
293516800b611a79339a3c188332d13a26e9086b09Adam Lesinskiimport android.view.MenuItem;
30e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinskiimport android.view.View;
31e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinskiimport android.view.ViewGroup;
32e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinskiimport android.widget.BaseAdapter;
33e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinskiimport android.widget.TextView;
34e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski
35e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinskiimport java.util.ArrayList;
36e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinskiimport java.util.Collections;
37e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinskiimport java.util.Comparator;
38cc562a811da508b275254f275d6e0c1758a47d07Adam Lesinskiimport java.util.Map;
39e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski
40e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinskipublic class UsageStatsActivity extends ListActivity {
413516800b611a79339a3c188332d13a26e9086b09Adam Lesinski    private static final long USAGE_STATS_PERIOD = 1000 * 60 * 60 * 24 * 14;
42e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski    private UsageStatsManager mUsageStatsManager;
43e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski    private Adapter mAdapter;
443516800b611a79339a3c188332d13a26e9086b09Adam Lesinski    private Comparator<UsageStats> mComparator = new Comparator<UsageStats>() {
45e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        @Override
463516800b611a79339a3c188332d13a26e9086b09Adam Lesinski        public int compare(UsageStats o1, UsageStats o2) {
473516800b611a79339a3c188332d13a26e9086b09Adam Lesinski            return Long.compare(o2.getTotalTimeInForeground(), o1.getTotalTimeInForeground());
48e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        }
49e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski    };
50e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski
51e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski    @Override
52e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski    protected void onCreate(Bundle savedInstanceState) {
53e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        super.onCreate(savedInstanceState);
54e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        mUsageStatsManager = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE);
55e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        mAdapter = new Adapter();
56e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        setListAdapter(mAdapter);
57e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski    }
58e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski
59e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski    @Override
603516800b611a79339a3c188332d13a26e9086b09Adam Lesinski    public boolean onCreateOptionsMenu(Menu menu) {
613516800b611a79339a3c188332d13a26e9086b09Adam Lesinski        MenuInflater inflater = getMenuInflater();
623516800b611a79339a3c188332d13a26e9086b09Adam Lesinski        inflater.inflate(R.menu.main, menu);
633516800b611a79339a3c188332d13a26e9086b09Adam Lesinski        return super.onCreateOptionsMenu(menu);
643516800b611a79339a3c188332d13a26e9086b09Adam Lesinski    }
653516800b611a79339a3c188332d13a26e9086b09Adam Lesinski
663516800b611a79339a3c188332d13a26e9086b09Adam Lesinski    @Override
673516800b611a79339a3c188332d13a26e9086b09Adam Lesinski    public boolean onOptionsItemSelected(MenuItem item) {
683516800b611a79339a3c188332d13a26e9086b09Adam Lesinski        switch (item.getItemId()) {
693516800b611a79339a3c188332d13a26e9086b09Adam Lesinski            case R.id.log:
703516800b611a79339a3c188332d13a26e9086b09Adam Lesinski                startActivity(new Intent(this, UsageLogActivity.class));
713516800b611a79339a3c188332d13a26e9086b09Adam Lesinski                return true;
723516800b611a79339a3c188332d13a26e9086b09Adam Lesinski
733516800b611a79339a3c188332d13a26e9086b09Adam Lesinski            default:
743516800b611a79339a3c188332d13a26e9086b09Adam Lesinski                return super.onOptionsItemSelected(item);
753516800b611a79339a3c188332d13a26e9086b09Adam Lesinski        }
763516800b611a79339a3c188332d13a26e9086b09Adam Lesinski    }
773516800b611a79339a3c188332d13a26e9086b09Adam Lesinski
783516800b611a79339a3c188332d13a26e9086b09Adam Lesinski    @Override
79e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski    protected void onResume() {
80e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        super.onResume();
81e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        updateAdapter();
82e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski    }
83e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski
84e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski    private void updateAdapter() {
853516800b611a79339a3c188332d13a26e9086b09Adam Lesinski        long now = System.currentTimeMillis();
863516800b611a79339a3c188332d13a26e9086b09Adam Lesinski        long beginTime = now - USAGE_STATS_PERIOD;
87cc562a811da508b275254f275d6e0c1758a47d07Adam Lesinski        Map<String, UsageStats> stats = mUsageStatsManager.queryAndAggregateUsageStats(
883516800b611a79339a3c188332d13a26e9086b09Adam Lesinski                beginTime, now);
89e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        mAdapter.update(stats);
90e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski    }
91e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski
92e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski    private class Adapter extends BaseAdapter {
933516800b611a79339a3c188332d13a26e9086b09Adam Lesinski        private ArrayList<UsageStats> mStats = new ArrayList<>();
94e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski
95cc562a811da508b275254f275d6e0c1758a47d07Adam Lesinski        public void update(Map<String, UsageStats> stats) {
96e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski            mStats.clear();
97e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski            if (stats == null) {
98e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski                return;
99e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski            }
100e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski
101cc562a811da508b275254f275d6e0c1758a47d07Adam Lesinski            mStats.addAll(stats.values());
102e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski            Collections.sort(mStats, mComparator);
103e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski            notifyDataSetChanged();
104e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        }
105e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski
106e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        @Override
107e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        public int getCount() {
108e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski            return mStats.size();
109e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        }
110e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski
111e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        @Override
112e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        public Object getItem(int position) {
113e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski            return mStats.get(position);
114e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        }
115e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski
116e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        @Override
117e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        public long getItemId(int position) {
118e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski            return position;
119e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        }
120e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski
121e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        @Override
122e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        public View getView(int position, View convertView, ViewGroup parent) {
123e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski            final ViewHolder holder;
124e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski            if (convertView == null) {
125e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski                convertView = LayoutInflater.from(UsageStatsActivity.this)
126e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski                        .inflate(R.layout.row_item, parent, false);
127e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski                holder = new ViewHolder();
128e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski                holder.packageName = (TextView) convertView.findViewById(android.R.id.text1);
129e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski                holder.usageTime = (TextView) convertView.findViewById(android.R.id.text2);
130e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski                convertView.setTag(holder);
131e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski            } else {
132e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski                holder = (ViewHolder) convertView.getTag();
133e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski            }
134e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski
135e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski            holder.packageName.setText(mStats.get(position).getPackageName());
136e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski            holder.usageTime.setText(DateUtils.formatDuration(
1373516800b611a79339a3c188332d13a26e9086b09Adam Lesinski                    mStats.get(position).getTotalTimeInForeground()));
138e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski            return convertView;
139e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        }
140e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski    }
141e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski
142e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski    private static class ViewHolder {
143e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        TextView packageName;
144e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski        TextView usageTime;
145e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski    }
146e159e2e0b83f9ea9d48f4c8666f9536e9338a70cAdam Lesinski}