RootsFragment.java revision 2036dad877336bf4d81202c334b1f2c81462bd9f
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 1935820cfe963ce120a5876b8a123d5b1df13cbac5Steve McKayimport static com.android.documentsui.Shared.DEBUG; 2035820cfe963ce120a5876b8a123d5b1df13cbac5Steve McKay 2166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.app.Fragment; 2266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.app.FragmentManager; 2366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.app.FragmentTransaction; 24a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkeyimport android.app.LoaderManager.LoaderCallbacks; 2566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.content.Context; 2654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkeyimport android.content.Intent; 27a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkeyimport android.content.Loader; 2854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkeyimport android.content.pm.PackageManager; 2954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkeyimport android.content.pm.ResolveInfo; 30c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkeyimport android.net.Uri; 3166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.os.Bundle; 32c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkeyimport android.provider.Settings; 334ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkeyimport android.text.TextUtils; 349fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkeyimport android.text.format.Formatter; 3535820cfe963ce120a5876b8a123d5b1df13cbac5Steve McKayimport android.util.Log; 3666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.view.LayoutInflater; 3766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.view.View; 3866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.view.ViewGroup; 3966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.widget.AdapterView; 4066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.widget.AdapterView.OnItemClickListener; 41c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkeyimport android.widget.AdapterView.OnItemLongClickListener; 4266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.widget.ArrayAdapter; 4366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.widget.ImageView; 4466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.widget.ListView; 4566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeyimport android.widget.TextView; 4666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 47ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeyimport com.android.documentsui.model.DocumentInfo; 48ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeyimport com.android.documentsui.model.RootInfo; 4966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 5058efce36cd1b26006e08ddd696292bf06fc34c81Steve McKayimport java.util.ArrayList; 51a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkeyimport java.util.Collection; 526efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkeyimport java.util.Collections; 53aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyimport java.util.Comparator; 5454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkeyimport java.util.List; 55e6585b32ea586743258a5457e2184ffc087f2d2fKenny Rootimport java.util.Objects; 5666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 5766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey/** 5866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey * Display list of known storage backend roots. 5966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey */ 6066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkeypublic class RootsFragment extends Fragment { 6166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 6235820cfe963ce120a5876b8a123d5b1df13cbac5Steve McKay private static final String TAG = "RootsFragment"; 6335820cfe963ce120a5876b8a123d5b1df13cbac5Steve McKay private static final String EXTRA_INCLUDE_APPS = "includeApps"; 6435820cfe963ce120a5876b8a123d5b1df13cbac5Steve McKay 6566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey private ListView mList; 666efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey private RootsAdapter mAdapter; 67a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey private LoaderCallbacks<Collection<RootInfo>> mCallbacks; 68a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 6954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 7054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey public static void show(FragmentManager fm, Intent includeApps) { 7154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey final Bundle args = new Bundle(); 7254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey args.putParcelable(EXTRA_INCLUDE_APPS, includeApps); 7354ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 7466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey final RootsFragment fragment = new RootsFragment(); 7554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey fragment.setArguments(args); 7666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 7766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey final FragmentTransaction ft = fm.beginTransaction(); 7866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey ft.replace(R.id.container_roots, fragment); 7966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey ft.commitAllowingStateLoss(); 8066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 8166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 8266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey public static RootsFragment get(FragmentManager fm) { 8366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey return (RootsFragment) fm.findFragmentById(R.id.container_roots); 8466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 8566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 8666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey @Override 8766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey public View onCreateView( 8866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 8966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey final Context context = inflater.getContext(); 9066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 9166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey final View view = inflater.inflate(R.layout.fragment_roots, container, false); 922036dad877336bf4d81202c334b1f2c81462bd9fBen Kwa mList = (ListView) view.findViewById(R.id.roots_list); 9366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey mList.setOnItemClickListener(mItemListener); 9428c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey mList.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 9566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey return view; 9666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 9766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 989fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey @Override 99a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey public void onActivityCreated(Bundle savedInstanceState) { 100a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey super.onActivityCreated(savedInstanceState); 101a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 102a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey final Context context = getActivity(); 103a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey final RootsCache roots = DocumentsApplication.getRootsCache(context); 104e934ce6f8430f50d1d22bccd3b341b982f5541eeSteve McKay final State state = ((BaseActivity) context).getDisplayState(); 105a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 106a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey mCallbacks = new LoaderCallbacks<Collection<RootInfo>>() { 107a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey @Override 108a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey public Loader<Collection<RootInfo>> onCreateLoader(int id, Bundle args) { 109a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey return new RootsLoader(context, roots, state); 110a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey } 111a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 112a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey @Override 113a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey public void onLoadFinished( 114a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey Loader<Collection<RootInfo>> loader, Collection<RootInfo> result) { 115a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey if (!isAdded()) return; 116a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 117a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey final Intent includeApps = getArguments().getParcelable(EXTRA_INCLUDE_APPS); 118a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 1196efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey mAdapter = new RootsAdapter(context, result, includeApps); 120a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey mList.setAdapter(mAdapter); 121a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 122a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey onCurrentRootChanged(); 123a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey } 124a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 125a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey @Override 126a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey public void onLoaderReset(Loader<Collection<RootInfo>> loader) { 127a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey mAdapter = null; 128a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey mList.setAdapter(null); 129a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey } 130a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey }; 131a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey } 132a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 133a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey @Override 13488f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey public void onResume() { 13588f322c3115e85bb96fb46f9192b5daecd472c64Jeff Sharkey super.onResume(); 136669f8e7c70c595964a1c9ca154ac123da84d99a1Jeff Sharkey onDisplayStateChanged(); 137669f8e7c70c595964a1c9ca154ac123da84d99a1Jeff Sharkey } 1389fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 139669f8e7c70c595964a1c9ca154ac123da84d99a1Jeff Sharkey public void onDisplayStateChanged() { 1409fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey final Context context = getActivity(); 141e934ce6f8430f50d1d22bccd3b341b982f5541eeSteve McKay final State state = ((BaseActivity) context).getDisplayState(); 142348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey 143e934ce6f8430f50d1d22bccd3b341b982f5541eeSteve McKay if (state.action == State.ACTION_GET_CONTENT) { 144c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey mList.setOnItemLongClickListener(mItemLongClickListener); 145c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey } else { 146c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey mList.setOnItemLongClickListener(null); 147c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey mList.setLongClickable(false); 148c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey } 149c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey 150a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey getLoaderManager().restartLoader(2, null, mCallbacks); 15128c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey } 15228c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey 15328c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey public void onCurrentRootChanged() { 15428c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey if (mAdapter == null) return; 15528c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey 156e934ce6f8430f50d1d22bccd3b341b982f5541eeSteve McKay final RootInfo root = ((BaseActivity) getActivity()).getCurrentRoot(); 15728c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey for (int i = 0; i < mAdapter.getCount(); i++) { 15828c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey final Object item = mAdapter.getItem(i); 159a82c2e24bc226c123075331cdaafb171b3b07b85Jeff Sharkey if (item instanceof RootItem) { 160a82c2e24bc226c123075331cdaafb171b3b07b85Jeff Sharkey final RootInfo testRoot = ((RootItem) item).root; 161e6585b32ea586743258a5457e2184ffc087f2d2fKenny Root if (Objects.equals(testRoot, root)) { 162a82c2e24bc226c123075331cdaafb171b3b07b85Jeff Sharkey mList.setItemChecked(i, true); 1638e1c9637ec56fbfe313e964a5b60986c1bb092b9Aga Wronska mList.setSelection(i); 164a82c2e24bc226c123075331cdaafb171b3b07b85Jeff Sharkey return; 165a82c2e24bc226c123075331cdaafb171b3b07b85Jeff Sharkey } 16628c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey } 16728c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey } 1689fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey } 1699fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 1702036dad877336bf4d81202c334b1f2c81462bd9fBen Kwa /** 1712036dad877336bf4d81202c334b1f2c81462bd9fBen Kwa * Attempts to shift focus back to the navigation drawer. 1722036dad877336bf4d81202c334b1f2c81462bd9fBen Kwa */ 1732036dad877336bf4d81202c334b1f2c81462bd9fBen Kwa public void requestFocus() { 1742036dad877336bf4d81202c334b1f2c81462bd9fBen Kwa mList.requestFocus(); 1752036dad877336bf4d81202c334b1f2c81462bd9fBen Kwa } 1762036dad877336bf4d81202c334b1f2c81462bd9fBen Kwa 177c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey private void showAppDetails(ResolveInfo ri) { 178c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey final Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); 179c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey intent.setData(Uri.fromParts("package", ri.activityInfo.packageName, null)); 180c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 181c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey startActivity(intent); 182c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey } 183c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey 18466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey private OnItemClickListener mItemListener = new OnItemClickListener() { 18566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey @Override 18666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 187ef3e2cf35fbede340d5ff830b410baea8e461a94Steve McKay Item item = mAdapter.getItem(position); 1886efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey if (item instanceof RootItem) { 189ef3e2cf35fbede340d5ff830b410baea8e461a94Steve McKay BaseActivity activity = BaseActivity.get(RootsFragment.this); 19045f75e2a81674d792077516f13088d476c0ba510Aga Wronska RootInfo newRoot = ((RootItem) item).root; 19145f75e2a81674d792077516f13088d476c0ba510Aga Wronska Metrics.logRootVisited(getActivity(), newRoot); 19245f75e2a81674d792077516f13088d476c0ba510Aga Wronska activity.onRootPicked(newRoot); 1936efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } else if (item instanceof AppItem) { 194ef3e2cf35fbede340d5ff830b410baea8e461a94Steve McKay DocumentsActivity activity = DocumentsActivity.get(RootsFragment.this); 195723799858a15fa316128716d9e131a681d1a51d2Ben Kwa ResolveInfo info = ((AppItem) item).info; 196723799858a15fa316128716d9e131a681d1a51d2Ben Kwa Metrics.logAppVisited(getActivity(), info); 197723799858a15fa316128716d9e131a681d1a51d2Ben Kwa activity.onAppPicked(info); 19835820cfe963ce120a5876b8a123d5b1df13cbac5Steve McKay } else if (item instanceof SpacerItem) { 19935820cfe963ce120a5876b8a123d5b1df13cbac5Steve McKay if (DEBUG) Log.d(TAG, "Ignoring click on spacer item."); 20054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } else { 20154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey throw new IllegalStateException("Unknown root: " + item); 20254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } 20366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 20466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey }; 20566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 206c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey private OnItemLongClickListener mItemLongClickListener = new OnItemLongClickListener() { 207c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey @Override 208c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { 209c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey final Item item = mAdapter.getItem(position); 210c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey if (item instanceof AppItem) { 211c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey showAppDetails(((AppItem) item).info); 212c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey return true; 213c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey } else { 214c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey return false; 215c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey } 216c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey } 217c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey }; 218c24bbd4ce525d80e385de6e27b19dac239db1dfdJeff Sharkey 2196efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey private static abstract class Item { 2206efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey private final int mLayoutId; 2216efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 2226efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey public Item(int layoutId) { 2236efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey mLayoutId = layoutId; 22466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 22566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 2266efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey public View getView(View convertView, ViewGroup parent) { 22766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey if (convertView == null) { 2286efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey convertView = LayoutInflater.from(parent.getContext()) 2296efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey .inflate(mLayoutId, parent, false); 23066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 2316efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey bindView(convertView); 2326efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey return convertView; 2336efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 2346efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 2356efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey public abstract void bindView(View convertView); 2366efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 23766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 2386efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey private static class RootItem extends Item { 2396efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey public final RootInfo root; 2406efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 2416efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey public RootItem(RootInfo root) { 2426efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey super(R.layout.item_root); 2436efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey this.root = root; 2446efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 2456efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 2466efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey @Override 2476efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey public void bindView(View convertView) { 24866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon); 24966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey final TextView title = (TextView) convertView.findViewById(android.R.id.title); 25066516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey final TextView summary = (TextView) convertView.findViewById(android.R.id.summary); 25166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 2526efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey final Context context = convertView.getContext(); 253cbce47001e15be85b084c36a64c20039a0c4a667Jeff Sharkey icon.setImageDrawable(root.loadDrawerIcon(context)); 25466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey title.setText(root.title); 25566516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 2566efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey // Show available space if no summary 2576efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey String summaryText = root.summary; 2586efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey if (TextUtils.isEmpty(summaryText) && root.availableBytes >= 0) { 2599fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey summaryText = context.getString(R.string.root_available_bytes, 2609fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey Formatter.formatFileSize(context, root.availableBytes)); 2619fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey } 2629fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 2639fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey summary.setText(summaryText); 2644ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey summary.setVisibility(TextUtils.isEmpty(summaryText) ? View.GONE : View.VISIBLE); 2656efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 2666efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 26766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 2686efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey private static class SpacerItem extends Item { 2696efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey public SpacerItem() { 2706efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey super(R.layout.item_root_spacer); 27166516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 27266516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 27366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey @Override 2746efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey public void bindView(View convertView) { 2756efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey // Nothing to bind 27666516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 27766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 27866516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 2796efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey private static class AppItem extends Item { 2806efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey public final ResolveInfo info; 2816efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 2826efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey public AppItem(ResolveInfo info) { 2836efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey super(R.layout.item_root); 2846efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey this.info = info; 28554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } 28654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 28754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey @Override 2886efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey public void bindView(View convertView) { 28954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon); 29054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey final TextView title = (TextView) convertView.findViewById(android.R.id.title); 29154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey final TextView summary = (TextView) convertView.findViewById(android.R.id.summary); 29254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 2936efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey final PackageManager pm = convertView.getContext().getPackageManager(); 29454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey icon.setImageDrawable(info.loadIcon(pm)); 29554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey title.setText(info.loadLabel(pm)); 29654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 29754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey // TODO: match existing summary behavior from disambig dialog 29854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey summary.setVisibility(View.GONE); 29954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } 3006efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 30154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 3026efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey private static class RootsAdapter extends ArrayAdapter<Item> { 3036efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey public RootsAdapter(Context context, Collection<RootInfo> roots, Intent includeApps) { 3046efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey super(context, 0); 30554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 3060c64308240a7e9d3a78d4dedba2a419da63b5afdBen Kwa final List<RootItem> libraries = new ArrayList<>(); 307abf397458dca89fd3df4234d547a94bf0487033dDaichi Hirono final List<RootItem> others = new ArrayList<>(); 308abf397458dca89fd3df4234d547a94bf0487033dDaichi Hirono 309abf397458dca89fd3df4234d547a94bf0487033dDaichi Hirono for (final RootInfo root : roots) { 310abf397458dca89fd3df4234d547a94bf0487033dDaichi Hirono final RootItem item = new RootItem(root); 311e95c321fd991773e895e71bc415afff46236c77bBen Kwa if (root.isLibrary()) { 3123ce95951bd173c422b8d369b4651c28e5bcc20f4Steve McKay if (DEBUG) Log.d(TAG, "Adding " + root + " as library."); 313abf397458dca89fd3df4234d547a94bf0487033dDaichi Hirono libraries.add(item); 314abf397458dca89fd3df4234d547a94bf0487033dDaichi Hirono } else { 3153ce95951bd173c422b8d369b4651c28e5bcc20f4Steve McKay if (DEBUG) Log.d(TAG, "Adding " + root + " as non-library."); 316abf397458dca89fd3df4234d547a94bf0487033dDaichi Hirono others.add(item); 3175545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey } 3186efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 3195545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey 3206efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey final RootComparator comp = new RootComparator(); 3210c64308240a7e9d3a78d4dedba2a419da63b5afdBen Kwa Collections.sort(libraries, comp); 322abf397458dca89fd3df4234d547a94bf0487033dDaichi Hirono Collections.sort(others, comp); 3236efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 3240c64308240a7e9d3a78d4dedba2a419da63b5afdBen Kwa addAll(libraries); 3250c64308240a7e9d3a78d4dedba2a419da63b5afdBen Kwa add(new SpacerItem()); 326abf397458dca89fd3df4234d547a94bf0487033dDaichi Hirono addAll(others); 32766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 32854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey if (includeApps != null) { 32954ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey final PackageManager pm = context.getPackageManager(); 33054ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey final List<ResolveInfo> infos = pm.queryIntentActivities( 33154ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey includeApps, PackageManager.MATCH_DEFAULT_ONLY); 33254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 33358efce36cd1b26006e08ddd696292bf06fc34c81Steve McKay final List<AppItem> apps = new ArrayList<>(); 3346efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 33554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey // Omit ourselves from the list 33654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey for (ResolveInfo info : infos) { 33754ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey if (!context.getPackageName().equals(info.activityInfo.packageName)) { 3386efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey apps.add(new AppItem(info)); 3396efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 3406efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 3416efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 3426efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey if (apps.size() > 0) { 3436efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey add(new SpacerItem()); 3440c64308240a7e9d3a78d4dedba2a419da63b5afdBen Kwa addAll(apps); 34554ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } 34654ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } 3476efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 34854ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey 3496efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey @Override 3506efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey public View getView(int position, View convertView, ViewGroup parent) { 3516efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey final Item item = getItem(position); 3526efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey return item.getView(convertView, parent); 3536efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 35466516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey 3556efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey @Override 3566efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey public boolean areAllItemsEnabled() { 3576efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey return false; 3586efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 3596efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 3606efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey @Override 3616efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey public boolean isEnabled(int position) { 3626efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey return getItemViewType(position) != 1; 3636efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 3646efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 3656efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey @Override 3666efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey public int getItemViewType(int position) { 3676efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey final Item item = getItem(position); 3686efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey if (item instanceof RootItem || item instanceof AppItem) { 3696efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey return 0; 3706efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } else { 3716efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey return 1; 37254ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey } 37366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 3746efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 3756efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey @Override 3766efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey public int getViewTypeCount() { 3776efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey return 2; 3786efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 37966516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey } 380aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 3810c64308240a7e9d3a78d4dedba2a419da63b5afdBen Kwa public static class RootComparator implements Comparator<RootItem> { 382aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey @Override 3830c64308240a7e9d3a78d4dedba2a419da63b5afdBen Kwa public int compare(RootItem lhs, RootItem rhs) { 3840c64308240a7e9d3a78d4dedba2a419da63b5afdBen Kwa // Sort by root type, then title, then summary. 3850c64308240a7e9d3a78d4dedba2a419da63b5afdBen Kwa int score = lhs.root.derivedType - rhs.root.derivedType; 386aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey if (score != 0) { 387aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return score; 388aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 3890c64308240a7e9d3a78d4dedba2a419da63b5afdBen Kwa score = DocumentInfo.compareToIgnoreCaseNullable(lhs.root.title, rhs.root.title); 3900c64308240a7e9d3a78d4dedba2a419da63b5afdBen Kwa if (score != 0) { 3910c64308240a7e9d3a78d4dedba2a419da63b5afdBen Kwa return score; 3920c64308240a7e9d3a78d4dedba2a419da63b5afdBen Kwa } 3930c64308240a7e9d3a78d4dedba2a419da63b5afdBen Kwa 3940c64308240a7e9d3a78d4dedba2a419da63b5afdBen Kwa return DocumentInfo.compareToIgnoreCaseNullable(lhs.root.summary, rhs.root.summary); 395aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 396aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 39766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey} 398