RootsFragment.java revision a9ce049db87259e302e2368d2a4a1c11a94fd831
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; 22a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkeyimport android.app.LoaderManager.LoaderCallbacks; 2366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.content.Context; 2454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkeyimport android.content.Intent; 25a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkeyimport android.content.Loader; 2654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkeyimport android.content.pm.PackageManager; 2754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkeyimport android.content.pm.ResolveInfo; 2866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.os.Bundle; 29ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeyimport android.provider.DocumentsContract.Root; 304ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkeyimport android.text.TextUtils; 319fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkeyimport android.text.format.Formatter; 3266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.view.LayoutInflater; 3366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.view.View; 3466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.view.ViewGroup; 3566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.widget.AdapterView; 3666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.widget.AdapterView.OnItemClickListener; 3766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.widget.ArrayAdapter; 3866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.widget.ImageView; 3966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.widget.ListView; 40f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkeyimport android.widget.Space; 4166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.widget.TextView; 4266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 43348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkeyimport com.android.documentsui.DocumentsActivity.State; 4466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport com.android.documentsui.SectionedListAdapter.SectionAdapter; 45ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeyimport com.android.documentsui.model.DocumentInfo; 46ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeyimport com.android.documentsui.model.RootInfo; 4728c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkeyimport com.android.internal.util.Objects; 4866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 49a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkeyimport java.util.Collection; 50aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyimport java.util.Comparator; 5154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkeyimport java.util.List; 5266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 5366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey/** 5466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * Display list of known storage backend roots. 5566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey */ 5666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeypublic class RootsFragment extends Fragment { 5766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 5866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey private ListView mList; 5966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey private SectionedRootsAdapter mAdapter; 6066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 61a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey private LoaderCallbacks<Collection<RootInfo>> mCallbacks; 62a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 6354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey private static final String EXTRA_INCLUDE_APPS = "includeApps"; 6454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 6554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey public static void show(FragmentManager fm, Intent includeApps) { 6654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey final Bundle args = new Bundle(); 6754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey args.putParcelable(EXTRA_INCLUDE_APPS, includeApps); 6854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 6966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey final RootsFragment fragment = new RootsFragment(); 7054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey fragment.setArguments(args); 7166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 7266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey final FragmentTransaction ft = fm.beginTransaction(); 7366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey ft.replace(R.id.container_roots, fragment); 7466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey ft.commitAllowingStateLoss(); 7566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 7666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 7766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey public static RootsFragment get(FragmentManager fm) { 7866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey return (RootsFragment) fm.findFragmentById(R.id.container_roots); 7966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 8066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 8166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey @Override 8266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey public View onCreateView( 8366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 8466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey final Context context = inflater.getContext(); 8566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 8666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey final View view = inflater.inflate(R.layout.fragment_roots, container, false); 8766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey mList = (ListView) view.findViewById(android.R.id.list); 8866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey mList.setOnItemClickListener(mItemListener); 8928c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey mList.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 9066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 9166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey return view; 9266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 9366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 949fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey @Override 95a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey public void onActivityCreated(Bundle savedInstanceState) { 96a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey super.onActivityCreated(savedInstanceState); 97a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 98a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey final Context context = getActivity(); 99a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey final RootsCache roots = DocumentsApplication.getRootsCache(context); 100a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey final State state = ((DocumentsActivity) context).getDisplayState(); 101a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 102a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey mCallbacks = new LoaderCallbacks<Collection<RootInfo>>() { 103a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey @Override 104a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey public Loader<Collection<RootInfo>> onCreateLoader(int id, Bundle args) { 105a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey return new RootsLoader(context, roots, state); 106a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey } 107a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 108a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey @Override 109a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey public void onLoadFinished( 110a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey Loader<Collection<RootInfo>> loader, Collection<RootInfo> result) { 111a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey if (!isAdded()) return; 112a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 113a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey final Intent includeApps = getArguments().getParcelable(EXTRA_INCLUDE_APPS); 114a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 115a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey mAdapter = new SectionedRootsAdapter(context, result, includeApps); 116a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey mList.setAdapter(mAdapter); 117a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 118a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey onCurrentRootChanged(); 119a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey } 120a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 121a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey @Override 122a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey public void onLoaderReset(Loader<Collection<RootInfo>> loader) { 123a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey mAdapter = null; 124a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey mList.setAdapter(null); 125a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey } 126a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey }; 127a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey } 128a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 129a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey @Override 13088f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey public void onResume() { 13188f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey super.onResume(); 1329fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 1339fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey final Context context = getActivity(); 134348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey final State state = ((DocumentsActivity) context).getDisplayState(); 135348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey state.showAdvanced = SettingsActivity.getDisplayAdvancedDevices(context); 136348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey 137a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey getLoaderManager().restartLoader(2, null, mCallbacks); 13828c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey } 13928c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey 14028c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey public void onCurrentRootChanged() { 14128c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey if (mAdapter == null) return; 14228c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey 14328c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey final RootInfo root = ((DocumentsActivity) getActivity()).getCurrentRoot(); 14428c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey for (int i = 0; i < mAdapter.getCount(); i++) { 14528c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey final Object item = mAdapter.getItem(i); 14628c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey if (Objects.equal(item, root)) { 14728c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey mList.setItemChecked(i, true); 14828c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey return; 14928c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey } 15028c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey } 1519fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey } 1529fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 15366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey private OnItemClickListener mItemListener = new OnItemClickListener() { 15466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey @Override 15566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 15654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey final DocumentsActivity activity = DocumentsActivity.get(RootsFragment.this); 15754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey final Object item = mAdapter.getItem(position); 158ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey if (item instanceof RootInfo) { 159ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey activity.onRootPicked((RootInfo) item, true); 16054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } else if (item instanceof ResolveInfo) { 16154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey activity.onAppPicked((ResolveInfo) item); 16254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } else { 16354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey throw new IllegalStateException("Unknown root: " + item); 16454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } 16566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 16666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey }; 16766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 168ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey private static class RootsAdapter extends ArrayAdapter<RootInfo> implements SectionAdapter { 169f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey public RootsAdapter(Context context) { 17066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey super(context, 0); 17166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 17266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 17366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey @Override 17466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey public View getView(int position, View convertView, ViewGroup parent) { 1759fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey final Context context = parent.getContext(); 17666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey if (convertView == null) { 1779fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey convertView = LayoutInflater.from(context) 17866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey .inflate(R.layout.item_root, parent, false); 17966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 18066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 18166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon); 18266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey final TextView title = (TextView) convertView.findViewById(android.R.id.title); 18366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey final TextView summary = (TextView) convertView.findViewById(android.R.id.summary); 18466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 185ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey final RootInfo root = getItem(position); 186aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey icon.setImageDrawable(root.loadIcon(context)); 18766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey title.setText(root.title); 18866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 1899fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey // Device summary is always available space 1909fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey final String summaryText; 191ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey if (root.rootType == Root.ROOT_TYPE_DEVICE && root.availableBytes >= 0) { 1929fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey summaryText = context.getString(R.string.root_available_bytes, 1939fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey Formatter.formatFileSize(context, root.availableBytes)); 1949fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey } else { 1959fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey summaryText = root.summary; 1969fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey } 1979fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 1989fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey summary.setText(summaryText); 1994ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey summary.setVisibility(TextUtils.isEmpty(summaryText) ? View.GONE : View.VISIBLE); 20066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 20166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey return convertView; 20266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 20366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 20466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey @Override 20566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey public View getHeaderView(View convertView, ViewGroup parent) { 20666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey if (convertView == null) { 207f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey convertView = new Space(parent.getContext()); 20866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 20966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey return convertView; 21066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 21166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 21266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 21354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey private static class AppsAdapter extends ArrayAdapter<ResolveInfo> implements SectionAdapter { 21454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey public AppsAdapter(Context context) { 21554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey super(context, 0); 21654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } 21754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 21854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey @Override 21954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey public View getView(int position, View convertView, ViewGroup parent) { 22054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey final Context context = parent.getContext(); 22154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey final PackageManager pm = context.getPackageManager(); 22254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey if (convertView == null) { 22354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey convertView = LayoutInflater.from(context) 22454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey .inflate(R.layout.item_root, parent, false); 22554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } 22654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 22754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon); 22854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey final TextView title = (TextView) convertView.findViewById(android.R.id.title); 22954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey final TextView summary = (TextView) convertView.findViewById(android.R.id.summary); 23054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 23154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey final ResolveInfo info = getItem(position); 23254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey icon.setImageDrawable(info.loadIcon(pm)); 23354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey title.setText(info.loadLabel(pm)); 23454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 23554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey // TODO: match existing summary behavior from disambig dialog 23654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey summary.setVisibility(View.GONE); 23754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 23854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey return convertView; 23954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } 24054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 24154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey @Override 24254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey public View getHeaderView(View convertView, ViewGroup parent) { 24354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey if (convertView == null) { 24454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey convertView = LayoutInflater.from(parent.getContext()) 24554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey .inflate(R.layout.item_root_header, parent, false); 24654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } 24754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 24854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey final TextView title = (TextView) convertView.findViewById(android.R.id.title); 24954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey title.setText(R.string.root_type_apps); 25054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 25154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey return convertView; 25254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } 25354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } 25454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 25554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey private static class SectionedRootsAdapter extends SectionedListAdapter { 25666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey private final RootsAdapter mServices; 25766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey private final RootsAdapter mShortcuts; 25866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey private final RootsAdapter mDevices; 25954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey private final AppsAdapter mApps; 26066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 261a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey public SectionedRootsAdapter( 262a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey Context context, Collection<RootInfo> roots, Intent includeApps) { 263f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey mServices = new RootsAdapter(context); 264f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey mShortcuts = new RootsAdapter(context); 265f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey mDevices = new RootsAdapter(context); 26654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey mApps = new AppsAdapter(context); 26766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 268ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey for (RootInfo root : roots) { 26966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey switch (root.rootType) { 270ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey case Root.ROOT_TYPE_SERVICE: 27166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey mServices.add(root); 27266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey break; 273ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey case Root.ROOT_TYPE_SHORTCUT: 27466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey mShortcuts.add(root); 27566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey break; 276ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey case Root.ROOT_TYPE_DEVICE: 277348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey mDevices.add(root); 27866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey break; 27966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 28066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 28166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 28254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey if (includeApps != null) { 28354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey final PackageManager pm = context.getPackageManager(); 28454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey final List<ResolveInfo> infos = pm.queryIntentActivities( 28554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey includeApps, PackageManager.MATCH_DEFAULT_ONLY); 28654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 28754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey // Omit ourselves from the list 28854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey for (ResolveInfo info : infos) { 28954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey if (!context.getPackageName().equals(info.activityInfo.packageName)) { 29054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey mApps.add(info); 29154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } 29254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } 29354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } 29454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 29566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey final RootComparator comp = new RootComparator(); 29666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey mServices.sort(comp); 29766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey mShortcuts.sort(comp); 29866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey mDevices.sort(comp); 29966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 30066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey if (mShortcuts.getCount() > 0) { 30166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey addSection(mShortcuts); 30266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 303348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey if (mDevices.getCount() > 0) { 304348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey addSection(mDevices); 30566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 306f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey if (mServices.getCount() > 0) { 307f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey addSection(mServices); 308f6db154975ef575479ba4ab59d80bcf592288252Jeff Sharkey } 30954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey if (mApps.getCount() > 0) { 31054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey addSection(mApps); 31154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } 31266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 31366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 314aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 315ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey public static class RootComparator implements Comparator<RootInfo> { 316aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey @Override 317ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey public int compare(RootInfo lhs, RootInfo rhs) { 318348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey if (lhs.authority == null) { 319348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey return -1; 320348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey } else if (rhs.authority == null) { 321348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey return 1; 322348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey } 323348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey 324ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey final int score = DocumentInfo.compareToIgnoreCaseNullable(lhs.title, rhs.title); 325aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey if (score != 0) { 326aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return score; 327aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } else { 328ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return DocumentInfo.compareToIgnoreCaseNullable(lhs.summary, rhs.summary); 329aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 330aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 331aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 33266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey} 333