RootsFragment.java revision 348ad6866b91afa4d59d45df533ef88094c74d13
166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey/*
266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * Copyright (C) 2013 The Android Open Source Project
366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey *
466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * you may not use this file except in compliance with the License.
666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * You may obtain a copy of the License at
766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey *
866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey *
1066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * Unless required by applicable law or agreed to in writing, software
1166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
1266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * See the License for the specific language governing permissions and
1466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * limitations under the License.
1566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey */
1666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
1766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeypackage com.android.documentsui;
1866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
1966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.app.Fragment;
2066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.app.FragmentManager;
2166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.app.FragmentTransaction;
2266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.content.Context;
2354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkeyimport android.content.Intent;
2454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkeyimport android.content.pm.PackageManager;
2554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkeyimport android.content.pm.ResolveInfo;
2666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.os.Bundle;
27ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeyimport android.provider.DocumentsContract.Root;
289fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkeyimport android.text.format.Formatter;
2966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.view.LayoutInflater;
3066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.view.View;
3166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.view.ViewGroup;
3266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.widget.AdapterView;
3366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.widget.AdapterView.OnItemClickListener;
3466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.widget.ArrayAdapter;
3566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.widget.ImageView;
3666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.widget.ListView;
3766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.widget.TextView;
3866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
39348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkeyimport com.android.documentsui.DocumentsActivity.State;
4066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport com.android.documentsui.SectionedListAdapter.SectionAdapter;
41ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeyimport com.android.documentsui.model.DocumentInfo;
42ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeyimport com.android.documentsui.model.RootInfo;
4366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
44aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyimport java.util.Comparator;
4554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkeyimport java.util.List;
4666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
4766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey/**
4866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * Display list of known storage backend roots.
4966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey */
5066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeypublic class RootsFragment extends Fragment {
5166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
5266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    private ListView mList;
5366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    private SectionedRootsAdapter mAdapter;
5466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
5554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey    private static final String EXTRA_INCLUDE_APPS = "includeApps";
5654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey
5754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey    public static void show(FragmentManager fm, Intent includeApps) {
5854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey        final Bundle args = new Bundle();
5954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey        args.putParcelable(EXTRA_INCLUDE_APPS, includeApps);
6054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey
6166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        final RootsFragment fragment = new RootsFragment();
6254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey        fragment.setArguments(args);
6366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
6466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        final FragmentTransaction ft = fm.beginTransaction();
6566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        ft.replace(R.id.container_roots, fragment);
6666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        ft.commitAllowingStateLoss();
6766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
6866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
6966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public static RootsFragment get(FragmentManager fm) {
7066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        return (RootsFragment) fm.findFragmentById(R.id.container_roots);
7166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
7266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
7366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    @Override
7466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    public View onCreateView(
7566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
7666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        final Context context = inflater.getContext();
7766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
7866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        final View view = inflater.inflate(R.layout.fragment_roots, container, false);
7966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        mList = (ListView) view.findViewById(android.R.id.list);
8066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        mList.setOnItemClickListener(mItemListener);
8166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
8266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        return view;
8366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
8466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
859fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey    @Override
869fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey    public void onStart() {
879fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey        super.onStart();
88348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey        updateRootsAdapter();
89348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey    }
909fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey
91348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey    private void updateRootsAdapter() {
929fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey        final Context context = getActivity();
93348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey
94348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey        final State state = ((DocumentsActivity) context).getDisplayState();
95348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey        state.showAdvanced = SettingsActivity.getDisplayAdvancedDevices(context);
96348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey
97348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey        final RootsCache roots = DocumentsApplication.getRootsCache(context);
98348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey        final List<RootInfo> matchingRoots = roots.getMatchingRoots(state);
99348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey        final Intent includeApps = getArguments().getParcelable(EXTRA_INCLUDE_APPS);
100348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey
101348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey        mAdapter = new SectionedRootsAdapter(context, matchingRoots, includeApps);
10254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey        mList.setAdapter(mAdapter);
1039fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey    }
1049fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey
10566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    private OnItemClickListener mItemListener = new OnItemClickListener() {
10666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        @Override
10766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
10854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            final DocumentsActivity activity = DocumentsActivity.get(RootsFragment.this);
10954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            final Object item = mAdapter.getItem(position);
110ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey            if (item instanceof RootInfo) {
111ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey                activity.onRootPicked((RootInfo) item, true);
11254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            } else if (item instanceof ResolveInfo) {
11354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey                activity.onAppPicked((ResolveInfo) item);
11454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            } else {
11554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey                throw new IllegalStateException("Unknown root: " + item);
11654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            }
11766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        }
11866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    };
11966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
120ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey    private static class RootsAdapter extends ArrayAdapter<RootInfo> implements SectionAdapter {
12166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        private int mHeaderId;
12266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
12366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        public RootsAdapter(Context context, int headerId) {
12466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            super(context, 0);
12566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            mHeaderId = headerId;
12666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        }
12766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
12866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        @Override
12966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        public View getView(int position, View convertView, ViewGroup parent) {
1309fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey            final Context context = parent.getContext();
13166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            if (convertView == null) {
1329fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey                convertView = LayoutInflater.from(context)
13366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                        .inflate(R.layout.item_root, parent, false);
13466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            }
13566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
13666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon);
13766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
13866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            final TextView summary = (TextView) convertView.findViewById(android.R.id.summary);
13966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
140ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey            final RootInfo root = getItem(position);
141aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey            icon.setImageDrawable(root.loadIcon(context));
14266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            title.setText(root.title);
14366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
1449fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey            // Device summary is always available space
1459fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey            final String summaryText;
146ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey            if (root.rootType == Root.ROOT_TYPE_DEVICE && root.availableBytes >= 0) {
1479fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey                summaryText = context.getString(R.string.root_available_bytes,
1489fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey                        Formatter.formatFileSize(context, root.availableBytes));
1499fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey            } else {
1509fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey                summaryText = root.summary;
1519fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey            }
1529fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey
1539fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey            summary.setText(summaryText);
1549fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey            summary.setVisibility(summaryText != null ? View.VISIBLE : View.GONE);
15566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
15666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            return convertView;
15766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        }
15866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
15966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        @Override
16066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        public View getHeaderView(View convertView, ViewGroup parent) {
16166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            if (convertView == null) {
16266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                convertView = LayoutInflater.from(parent.getContext())
16366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                        .inflate(R.layout.item_root_header, parent, false);
16466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            }
16566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
16666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
16766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            title.setText(mHeaderId);
16866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
16966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            return convertView;
17066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        }
17166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
17266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
17354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey    private static class AppsAdapter extends ArrayAdapter<ResolveInfo> implements SectionAdapter {
17454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey        public AppsAdapter(Context context) {
17554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            super(context, 0);
17654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey        }
17754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey
17854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey        @Override
17954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey        public View getView(int position, View convertView, ViewGroup parent) {
18054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            final Context context = parent.getContext();
18154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            final PackageManager pm = context.getPackageManager();
18254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            if (convertView == null) {
18354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey                convertView = LayoutInflater.from(context)
18454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey                        .inflate(R.layout.item_root, parent, false);
18554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            }
18654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey
18754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon);
18854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
18954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            final TextView summary = (TextView) convertView.findViewById(android.R.id.summary);
19054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey
19154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            final ResolveInfo info = getItem(position);
19254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            icon.setImageDrawable(info.loadIcon(pm));
19354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            title.setText(info.loadLabel(pm));
19454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey
19554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            // TODO: match existing summary behavior from disambig dialog
19654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            summary.setVisibility(View.GONE);
19754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey
19854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            return convertView;
19954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey        }
20054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey
20154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey        @Override
20254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey        public View getHeaderView(View convertView, ViewGroup parent) {
20354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            if (convertView == null) {
20454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey                convertView = LayoutInflater.from(parent.getContext())
20554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey                        .inflate(R.layout.item_root_header, parent, false);
20654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            }
20754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey
20854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            final TextView title = (TextView) convertView.findViewById(android.R.id.title);
20954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            title.setText(R.string.root_type_apps);
21054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey
21154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            return convertView;
21254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey        }
21354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey    }
21454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey
21554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey    private static class SectionedRootsAdapter extends SectionedListAdapter {
21666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        private final RootsAdapter mServices;
21766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        private final RootsAdapter mShortcuts;
21866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        private final RootsAdapter mDevices;
21954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey        private final AppsAdapter mApps;
22066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
221ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey        public SectionedRootsAdapter(Context context, List<RootInfo> roots, Intent includeApps) {
22266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            mServices = new RootsAdapter(context, R.string.root_type_service);
22366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            mShortcuts = new RootsAdapter(context, R.string.root_type_shortcut);
22466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            mDevices = new RootsAdapter(context, R.string.root_type_device);
22554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            mApps = new AppsAdapter(context);
22666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
227ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey            for (RootInfo root : roots) {
22866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                switch (root.rootType) {
229ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey                    case Root.ROOT_TYPE_SERVICE:
23066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                        mServices.add(root);
23166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                        break;
232ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey                    case Root.ROOT_TYPE_SHORTCUT:
23366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                        mShortcuts.add(root);
23466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                        break;
235ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey                    case Root.ROOT_TYPE_DEVICE:
236348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey                        mDevices.add(root);
23766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                        break;
23866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                }
23966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            }
24066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
24154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            if (includeApps != null) {
24254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey                final PackageManager pm = context.getPackageManager();
24354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey                final List<ResolveInfo> infos = pm.queryIntentActivities(
24454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey                        includeApps, PackageManager.MATCH_DEFAULT_ONLY);
24554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey
24654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey                // Omit ourselves from the list
24754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey                for (ResolveInfo info : infos) {
24854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey                    if (!context.getPackageName().equals(info.activityInfo.packageName)) {
24954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey                        mApps.add(info);
25054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey                    }
25154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey                }
25254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            }
25354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey
25466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            final RootComparator comp = new RootComparator();
25566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            mServices.sort(comp);
25666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            mShortcuts.sort(comp);
25766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            mDevices.sort(comp);
25866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey
25966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            if (mServices.getCount() > 0) {
26066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                addSection(mServices);
26166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            }
26266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            if (mShortcuts.getCount() > 0) {
26366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey                addSection(mShortcuts);
26466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            }
265348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey            if (mDevices.getCount() > 0) {
266348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey                addSection(mDevices);
26766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey            }
26854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            if (mApps.getCount() > 0) {
26954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey                addSection(mApps);
27054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey            }
27166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey        }
27266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey    }
273aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey
274ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey    public static class RootComparator implements Comparator<RootInfo> {
275aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey        @Override
276ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey        public int compare(RootInfo lhs, RootInfo rhs) {
277348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey            if (lhs.authority == null) {
278348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey                return -1;
279348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey            } else if (rhs.authority == null) {
280348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey                return 1;
281348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey            }
282348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey
283ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey            final int score = DocumentInfo.compareToIgnoreCaseNullable(lhs.title, rhs.title);
284aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey            if (score != 0) {
285aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey                return score;
286aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey            } else {
287ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey                return DocumentInfo.compareToIgnoreCaseNullable(lhs.summary, rhs.summary);
288aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey            }
289aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey        }
290aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey    }
29166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey}
292