1e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski/*
2e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski * Copyright (C) 2015 The Android Open Source Project
3e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski *
4e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski * Licensed under the Apache License, Version 2.0 (the "License");
5e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski * you may not use this file except in compliance with the License.
6e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski * You may obtain a copy of the License at
7e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski *
8e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski *      http://www.apache.org/licenses/LICENSE-2.0
9e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski *
10e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski * Unless required by applicable law or agreed to in writing, software
11e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski * distributed under the License is distributed on an "AS IS" BASIS,
12e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski * See the License for the specific language governing permissions and
14e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski * limitations under the License.
15e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski */
16e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski
17e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynskipackage com.example.android.support.percent;
18e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski
1919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport android.app.ListActivity;
2019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport android.content.Intent;
2119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport android.content.pm.PackageManager;
2219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport android.content.pm.ResolveInfo;
23e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynskiimport android.os.Bundle;
24e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynskiimport android.view.View;
2519c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport android.widget.ListView;
2619c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport android.widget.SimpleAdapter;
27e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski
2819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport java.text.Collator;
2919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport java.util.ArrayList;
3019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport java.util.Collections;
3119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport java.util.Comparator;
3219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport java.util.HashMap;
3319c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport java.util.List;
3419c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovimport java.util.Map;
35e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski
3619c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikovpublic class SupportPercentDemos extends ListActivity {
37e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski
38e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski    @Override
3919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov    public void onCreate(Bundle savedInstanceState) {
40e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski        super.onCreate(savedInstanceState);
4119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov
4219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        Intent intent = getIntent();
4319c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        String path = intent.getStringExtra("com.example.android.apis.Path");
4419c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov
4519c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        if (path == null) {
4619c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov            path = "";
4719c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        }
4819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov
4919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        setListAdapter(new SimpleAdapter(this, getData(path),
5019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov                android.R.layout.simple_list_item_1, new String[] { "title" },
5119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov                new int[] { android.R.id.text1 }));
5219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        getListView().setTextFilterEnabled(true);
53e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski    }
54e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski
5519c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov    protected List<Map<String, Object>> getData(String prefix) {
5619c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        List<Map<String, Object>> myData = new ArrayList<Map<String, Object>>();
5719c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov
5819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
5919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        mainIntent.addCategory("com.example.android.supportpercent.SAMPLE_CODE");
6019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov
6119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        PackageManager pm = getPackageManager();
6219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);
6319c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov
6419c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        if (null == list)
6519c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov            return myData;
6619c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov
6719c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        String[] prefixPath;
6819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        String prefixWithSlash = prefix;
6919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov
7019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        if (prefix.equals("")) {
7119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov            prefixPath = null;
7219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        } else {
7319c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov            prefixPath = prefix.split("/");
7419c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov            prefixWithSlash = prefix + "/";
75e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski        }
76e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski
7719c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        int len = list.size();
7819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov
7919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        Map<String, Boolean> entries = new HashMap<String, Boolean>();
8019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov
8119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        for (int i = 0; i < len; i++) {
8219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov            ResolveInfo info = list.get(i);
8319c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov            CharSequence labelSeq = info.loadLabel(pm);
8419c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov            String label = labelSeq != null
8519c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov                    ? labelSeq.toString()
8619c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov                    : info.activityInfo.name;
8719c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov
8819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov            if (prefixWithSlash.length() == 0 || label.startsWith(prefixWithSlash)) {
8919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov
9019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov                String[] labelPath = label.split("/");
9119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov
9219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov                String nextLabel = prefixPath == null ? labelPath[0] : labelPath[prefixPath.length];
93973c8f507a83250d3aae077427bd4df67ba4ff61Filip Gruszczynski
9419c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov                if ((prefixPath != null ? prefixPath.length : 0) == labelPath.length - 1) {
9519c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov                    addItem(myData, nextLabel, activityIntent(
9619c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov                            info.activityInfo.applicationInfo.packageName,
9719c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov                            info.activityInfo.name));
9819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov                } else {
9919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov                    if (entries.get(nextLabel) == null) {
10019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov                        addItem(myData, nextLabel, browseIntent(
10119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov                                prefix.equals("") ? nextLabel : prefix + "/" + nextLabel));
10219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov                        entries.put(nextLabel, true);
10319c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov                    }
10419c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov                }
105e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski            }
106e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski        }
107e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski
10819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        Collections.sort(myData, sDisplayNameComparator);
10919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov
11019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        return myData;
111e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski    }
112e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski
11319c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov    private final static Comparator<Map<String, Object>> sDisplayNameComparator =
11419c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov            new Comparator<Map<String, Object>>() {
11519c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov                private final Collator collator = Collator.getInstance();
116e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski
11719c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov                @Override
11819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov                public int compare(Map<String, Object> map1, Map<String, Object> map2) {
11919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov                    return collator.compare(map1.get("title"), map2.get("title"));
12019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov                }
12119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov            };
12219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov
12319c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov    protected Intent activityIntent(String pkg, String componentName) {
12419c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        Intent result = new Intent();
12519c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        result.setClassName(pkg, componentName);
12619c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        return result;
12719c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov    }
12819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov
12919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov    protected Intent browseIntent(String path) {
13019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        Intent result = new Intent();
13119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        result.setClass(this, SupportPercentDemos.class);
13219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        result.putExtra("com.example.android.apis.Path", path);
13319c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        return result;
13419c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov    }
13519c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov
13619c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov    protected void addItem(List<Map<String, Object>> data, String name, Intent intent) {
13719c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        Map<String, Object> temp = new HashMap<String, Object>();
13819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        temp.put("title", name);
13919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        temp.put("intent", intent);
14019c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        data.add(temp);
14119c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov    }
14219c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov
14319c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov    @Override
14419c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov    @SuppressWarnings("unchecked")
14519c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov    protected void onListItemClick(ListView l, View v, int position, long id) {
14619c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        Map<String, Object> map = (Map<String, Object>)l.getItemAtPosition(position);
14719c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov
14819c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        Intent intent = (Intent) map.get("intent");
14919c7639c1f608b6238e898203420b2c63b7e9d11Kirill Grouchnikov        startActivity(intent);
150e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski    }
151e5275fa662cbd4839031f3a0f2212d976dfb53d3Filip Gruszczynski}
152