DocumentsActivity.java revision 4eb407a832b7d6a2d62a535e5cab70b00a0bc8ed
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.documentsui; 18 19import static com.android.documentsui.DocumentsActivity.DisplayState.ACTION_CREATE; 20import static com.android.documentsui.DocumentsActivity.DisplayState.ACTION_GET_CONTENT; 21import static com.android.documentsui.DocumentsActivity.DisplayState.ACTION_MANAGE; 22import static com.android.documentsui.DocumentsActivity.DisplayState.ACTION_OPEN; 23import static com.android.documentsui.DocumentsActivity.DisplayState.MODE_GRID; 24import static com.android.documentsui.DocumentsActivity.DisplayState.MODE_LIST; 25import static com.android.documentsui.DocumentsActivity.DisplayState.SORT_ORDER_DATE; 26 27import android.app.ActionBar; 28import android.app.ActionBar.OnNavigationListener; 29import android.app.Activity; 30import android.app.Fragment; 31import android.app.FragmentManager; 32import android.content.ActivityNotFoundException; 33import android.content.ClipData; 34import android.content.ComponentName; 35import android.content.ContentResolver; 36import android.content.ContentValues; 37import android.content.Intent; 38import android.content.pm.ResolveInfo; 39import android.database.Cursor; 40import android.graphics.drawable.ColorDrawable; 41import android.net.Uri; 42import android.os.Bundle; 43import android.provider.DocumentsContract; 44import android.provider.DocumentsContract.DocumentColumns; 45import android.support.v4.app.ActionBarDrawerToggle; 46import android.support.v4.view.GravityCompat; 47import android.support.v4.widget.DrawerLayout; 48import android.support.v4.widget.DrawerLayout.DrawerListener; 49import android.util.Log; 50import android.view.LayoutInflater; 51import android.view.Menu; 52import android.view.MenuItem; 53import android.view.View; 54import android.view.ViewGroup; 55import android.widget.BaseAdapter; 56import android.widget.SearchView; 57import android.widget.SearchView.OnCloseListener; 58import android.widget.SearchView.OnQueryTextListener; 59import android.widget.TextView; 60import android.widget.Toast; 61 62import com.android.documentsui.model.Document; 63import com.android.documentsui.model.DocumentStack; 64import com.android.documentsui.model.Root; 65 66import java.io.FileNotFoundException; 67import java.util.Arrays; 68import java.util.List; 69 70public class DocumentsActivity extends Activity { 71 public static final String TAG = "Documents"; 72 73 private int mAction; 74 75 private SearchView mSearchView; 76 77 private View mRootsContainer; 78 private DrawerLayout mDrawerLayout; 79 private ActionBarDrawerToggle mDrawerToggle; 80 81 private final DisplayState mDisplayState = new DisplayState(); 82 83 private RootsCache mRoots; 84 85 /** Current user navigation stack; empty implies recents. */ 86 private DocumentStack mStack = new DocumentStack(); 87 /** Currently active search, overriding any stack. */ 88 private String mCurrentSearch; 89 90 @Override 91 public void onCreate(Bundle icicle) { 92 super.onCreate(icicle); 93 94 mRoots = DocumentsApplication.getRootsCache(this); 95 96 final Intent intent = getIntent(); 97 final String action = intent.getAction(); 98 if (Intent.ACTION_OPEN_DOCUMENT.equals(action)) { 99 mAction = ACTION_OPEN; 100 } else if (Intent.ACTION_CREATE_DOCUMENT.equals(action)) { 101 mAction = ACTION_CREATE; 102 } else if (Intent.ACTION_GET_CONTENT.equals(action)) { 103 mAction = ACTION_GET_CONTENT; 104 } else if (Intent.ACTION_MANAGE_DOCUMENT.equals(action)) { 105 mAction = ACTION_MANAGE; 106 } 107 108 // TODO: unify action in single place 109 mDisplayState.action = mAction; 110 111 if (mAction == ACTION_OPEN || mAction == ACTION_GET_CONTENT) { 112 mDisplayState.allowMultiple = intent.getBooleanExtra( 113 Intent.EXTRA_ALLOW_MULTIPLE, false); 114 } 115 116 if (mAction == ACTION_MANAGE) { 117 mDisplayState.acceptMimes = new String[] { "*/*" }; 118 mDisplayState.allowMultiple = true; 119 } else if (intent.hasExtra(Intent.EXTRA_MIME_TYPES)) { 120 mDisplayState.acceptMimes = intent.getStringArrayExtra(Intent.EXTRA_MIME_TYPES); 121 } else { 122 mDisplayState.acceptMimes = new String[] { intent.getType() }; 123 } 124 125 mDisplayState.localOnly = intent.getBooleanExtra(Intent.EXTRA_LOCAL_ONLY, false); 126 127 setResult(Activity.RESULT_CANCELED); 128 setContentView(R.layout.activity); 129 130 if (mAction == ACTION_CREATE) { 131 final String mimeType = getIntent().getType(); 132 final String title = getIntent().getStringExtra(Intent.EXTRA_TITLE); 133 SaveFragment.show(getFragmentManager(), mimeType, title); 134 } 135 136 if (mAction == ACTION_GET_CONTENT) { 137 final Intent moreApps = new Intent(getIntent()); 138 moreApps.setComponent(null); 139 moreApps.setPackage(null); 140 RootsFragment.show(getFragmentManager(), moreApps); 141 } else if (mAction == ACTION_OPEN || mAction == ACTION_CREATE) { 142 RootsFragment.show(getFragmentManager(), null); 143 } 144 145 if (mAction == ACTION_MANAGE) { 146 mDisplayState.sortOrder = SORT_ORDER_DATE; 147 } 148 149 mRootsContainer = findViewById(R.id.container_roots); 150 151 mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); 152 153 mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, 154 R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close); 155 156 mDrawerLayout.setDrawerListener(mDrawerListener); 157 mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START); 158 159 if (mAction == ACTION_MANAGE) { 160 mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); 161 162 final Uri rootUri = intent.getData(); 163 final String authority = rootUri.getAuthority(); 164 final String rootId = DocumentsContract.getRootId(rootUri); 165 166 final Root root = mRoots.findRoot(authority, rootId); 167 if (root != null) { 168 onRootPicked(root, true); 169 } else { 170 Log.w(TAG, "Failed to find root: " + rootUri); 171 finish(); 172 } 173 174 } else { 175 mDrawerLayout.openDrawer(mRootsContainer); 176 177 // Restore last stack for calling package 178 // TODO: move into async loader 179 final String packageName = getCallingPackage(); 180 final Cursor cursor = getContentResolver() 181 .query(RecentsProvider.buildResume(packageName), null, null, null, null); 182 try { 183 if (cursor.moveToFirst()) { 184 final String raw = cursor.getString( 185 cursor.getColumnIndex(RecentsProvider.COL_PATH)); 186 mStack = DocumentStack.deserialize(getContentResolver(), raw); 187 } 188 } catch (FileNotFoundException e) { 189 Log.w(TAG, "Failed to resume", e); 190 } finally { 191 cursor.close(); 192 } 193 194 onCurrentDirectoryChanged(); 195 } 196 } 197 198 @Override 199 public void onStart() { 200 super.onStart(); 201 202 if (mAction == ACTION_MANAGE) { 203 mDisplayState.showSize = true; 204 } else { 205 mDisplayState.showSize = SettingsActivity.getDisplayFileSize(this); 206 } 207 } 208 209 private DrawerListener mDrawerListener = new DrawerListener() { 210 @Override 211 public void onDrawerSlide(View drawerView, float slideOffset) { 212 mDrawerToggle.onDrawerSlide(drawerView, slideOffset); 213 } 214 215 @Override 216 public void onDrawerOpened(View drawerView) { 217 mDrawerToggle.onDrawerOpened(drawerView); 218 updateActionBar(); 219 } 220 221 @Override 222 public void onDrawerClosed(View drawerView) { 223 mDrawerToggle.onDrawerClosed(drawerView); 224 updateActionBar(); 225 } 226 227 @Override 228 public void onDrawerStateChanged(int newState) { 229 mDrawerToggle.onDrawerStateChanged(newState); 230 } 231 }; 232 233 @Override 234 protected void onPostCreate(Bundle savedInstanceState) { 235 super.onPostCreate(savedInstanceState); 236 mDrawerToggle.syncState(); 237 } 238 239 public void updateActionBar() { 240 final ActionBar actionBar = getActionBar(); 241 242 actionBar.setDisplayShowHomeEnabled(true); 243 244 if (mDrawerLayout.isDrawerOpen(mRootsContainer)) { 245 actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); 246 actionBar.setIcon(new ColorDrawable()); 247 248 if (mAction == ACTION_OPEN || mAction == ACTION_GET_CONTENT) { 249 actionBar.setTitle(R.string.title_open); 250 } else if (mAction == ACTION_CREATE) { 251 actionBar.setTitle(R.string.title_save); 252 } 253 254 actionBar.setDisplayHomeAsUpEnabled(true); 255 mDrawerToggle.setDrawerIndicatorEnabled(true); 256 257 } else { 258 final Root root = getCurrentRoot(); 259 actionBar.setIcon(root != null ? root.icon : null); 260 261 if (root.isRecents) { 262 actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); 263 actionBar.setTitle(root.title); 264 } else { 265 actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); 266 actionBar.setTitle(null); 267 actionBar.setListNavigationCallbacks(mSortAdapter, mSortListener); 268 actionBar.setSelectedNavigationItem(mDisplayState.sortOrder); 269 } 270 271 if (mStack.size() > 1) { 272 actionBar.setDisplayHomeAsUpEnabled(true); 273 mDrawerToggle.setDrawerIndicatorEnabled(false); 274 } else if (mAction == ACTION_MANAGE) { 275 actionBar.setDisplayHomeAsUpEnabled(false); 276 mDrawerToggle.setDrawerIndicatorEnabled(false); 277 } else { 278 actionBar.setDisplayHomeAsUpEnabled(true); 279 mDrawerToggle.setDrawerIndicatorEnabled(true); 280 } 281 } 282 } 283 284 @Override 285 public boolean onCreateOptionsMenu(Menu menu) { 286 super.onCreateOptionsMenu(menu); 287 getMenuInflater().inflate(R.menu.activity, menu); 288 289 final MenuItem searchMenu = menu.findItem(R.id.menu_search); 290 mSearchView = (SearchView) searchMenu.getActionView(); 291 mSearchView.setOnQueryTextListener(new OnQueryTextListener() { 292 @Override 293 public boolean onQueryTextSubmit(String query) { 294 mCurrentSearch = query; 295 onCurrentDirectoryChanged(); 296 mSearchView.setIconified(true); 297 return true; 298 } 299 300 @Override 301 public boolean onQueryTextChange(String newText) { 302 return false; 303 } 304 }); 305 306 mSearchView.setOnCloseListener(new OnCloseListener() { 307 @Override 308 public boolean onClose() { 309 mCurrentSearch = null; 310 onCurrentDirectoryChanged(); 311 return false; 312 } 313 }); 314 315 return true; 316 } 317 318 @Override 319 public boolean onPrepareOptionsMenu(Menu menu) { 320 super.onPrepareOptionsMenu(menu); 321 322 final FragmentManager fm = getFragmentManager(); 323 final Document cwd = getCurrentDirectory(); 324 325 final MenuItem createDir = menu.findItem(R.id.menu_create_dir); 326 final MenuItem search = menu.findItem(R.id.menu_search); 327 final MenuItem grid = menu.findItem(R.id.menu_grid); 328 final MenuItem list = menu.findItem(R.id.menu_list); 329 final MenuItem settings = menu.findItem(R.id.menu_settings); 330 331 grid.setVisible(mDisplayState.mode != MODE_GRID); 332 list.setVisible(mDisplayState.mode != MODE_LIST); 333 334 final boolean searchVisible; 335 if (mAction == ACTION_CREATE) { 336 createDir.setVisible(cwd != null && cwd.isCreateSupported()); 337 searchVisible = false; 338 339 // No display options in recent directories 340 if (cwd == null) { 341 grid.setVisible(false); 342 list.setVisible(false); 343 } 344 345 SaveFragment.get(fm).setSaveEnabled(cwd != null && cwd.isCreateSupported()); 346 } else { 347 createDir.setVisible(false); 348 searchVisible = cwd != null && cwd.isSearchSupported(); 349 } 350 351 // TODO: close any search in-progress when hiding 352 search.setVisible(searchVisible); 353 354 settings.setVisible(mAction != ACTION_MANAGE); 355 356 return true; 357 } 358 359 @Override 360 public boolean onOptionsItemSelected(MenuItem item) { 361 if (mDrawerToggle.onOptionsItemSelected(item)) { 362 return true; 363 } 364 365 final int id = item.getItemId(); 366 if (id == android.R.id.home) { 367 onBackPressed(); 368 return true; 369 } else if (id == R.id.menu_create_dir) { 370 CreateDirectoryFragment.show(getFragmentManager()); 371 return true; 372 } else if (id == R.id.menu_search) { 373 return false; 374 } else if (id == R.id.menu_grid) { 375 // TODO: persist explicit user mode for cwd 376 mDisplayState.mode = MODE_GRID; 377 updateDisplayState(); 378 invalidateOptionsMenu(); 379 return true; 380 } else if (id == R.id.menu_list) { 381 // TODO: persist explicit user mode for cwd 382 mDisplayState.mode = MODE_LIST; 383 updateDisplayState(); 384 invalidateOptionsMenu(); 385 return true; 386 } else if (id == R.id.menu_settings) { 387 startActivity(new Intent(this, SettingsActivity.class)); 388 return true; 389 } else { 390 return super.onOptionsItemSelected(item); 391 } 392 } 393 394 @Override 395 public void onBackPressed() { 396 final int size = mStack.size(); 397 if (size > 1) { 398 mStack.pop(); 399 onCurrentDirectoryChanged(); 400 } else if (size == 1 && !mDrawerLayout.isDrawerOpen(mRootsContainer)) { 401 // TODO: open root drawer once we can capture back key 402 super.onBackPressed(); 403 } else { 404 super.onBackPressed(); 405 } 406 } 407 408 // TODO: support additional sort orders 409 private BaseAdapter mSortAdapter = new BaseAdapter() { 410 @Override 411 public int getCount() { 412 return mDisplayState.showSize ? 3 : 2; 413 } 414 415 @Override 416 public Object getItem(int position) { 417 switch (position) { 418 case 0: 419 return getText(R.string.sort_name); 420 case 1: 421 return getText(R.string.sort_date); 422 case 2: 423 return getText(R.string.sort_size); 424 default: 425 return null; 426 } 427 } 428 429 @Override 430 public long getItemId(int position) { 431 return position; 432 } 433 434 @Override 435 public View getView(int position, View convertView, ViewGroup parent) { 436 if (convertView == null) { 437 convertView = LayoutInflater.from(parent.getContext()) 438 .inflate(R.layout.item_title, parent, false); 439 } 440 441 final TextView title = (TextView) convertView.findViewById(android.R.id.title); 442 final TextView summary = (TextView) convertView.findViewById(android.R.id.summary); 443 444 final Document cwd = getCurrentDirectory(); 445 if (cwd != null) { 446 title.setText(cwd.displayName); 447 } else { 448 // No directory means recents 449 title.setText(R.string.root_recent); 450 } 451 452 summary.setText((String) getItem(position)); 453 454 return convertView; 455 } 456 457 @Override 458 public View getDropDownView(int position, View convertView, ViewGroup parent) { 459 if (convertView == null) { 460 convertView = LayoutInflater.from(parent.getContext()) 461 .inflate(android.R.layout.simple_dropdown_item_1line, parent, false); 462 } 463 464 final TextView text1 = (TextView) convertView.findViewById(android.R.id.text1); 465 text1.setText((String) getItem(position)); 466 467 return convertView; 468 } 469 }; 470 471 private OnNavigationListener mSortListener = new OnNavigationListener() { 472 @Override 473 public boolean onNavigationItemSelected(int itemPosition, long itemId) { 474 mDisplayState.sortOrder = itemPosition; 475 updateDisplayState(); 476 return true; 477 } 478 }; 479 480 public Root getCurrentRoot() { 481 final Document cwd = getCurrentDirectory(); 482 if (cwd != null) { 483 return mRoots.findRoot(cwd); 484 } else { 485 return mRoots.getRecentsRoot(); 486 } 487 } 488 489 public Document getCurrentDirectory() { 490 return mStack.peek(); 491 } 492 493 public DisplayState getDisplayState() { 494 return mDisplayState; 495 } 496 497 private void onCurrentDirectoryChanged() { 498 final FragmentManager fm = getFragmentManager(); 499 final Document cwd = getCurrentDirectory(); 500 501 if (cwd == null) { 502 // No directory means recents 503 if (mAction == ACTION_CREATE) { 504 RecentsCreateFragment.show(fm); 505 } else { 506 DirectoryFragment.showRecentsOpen(fm); 507 } 508 } else { 509 if (mCurrentSearch != null) { 510 // Ongoing search 511 DirectoryFragment.showSearch(fm, cwd.uri, mCurrentSearch); 512 } else { 513 // Normal boring directory 514 DirectoryFragment.showNormal(fm, cwd.uri); 515 } 516 } 517 518 // Forget any replacement target 519 if (mAction == ACTION_CREATE) { 520 final SaveFragment save = SaveFragment.get(fm); 521 if (save != null) { 522 save.setReplaceTarget(null); 523 } 524 } 525 526 updateActionBar(); 527 invalidateOptionsMenu(); 528 dumpStack(); 529 } 530 531 private void updateDisplayState() { 532 // TODO: handle multiple directory stacks on tablets 533 DirectoryFragment.get(getFragmentManager()).updateDisplayState(); 534 } 535 536 public void onStackPicked(DocumentStack stack) { 537 mStack = stack; 538 onCurrentDirectoryChanged(); 539 } 540 541 public void onRootPicked(Root root, boolean closeDrawer) { 542 // Clear entire backstack and start in new root 543 mStack.clear(); 544 545 if (!root.isRecents) { 546 try { 547 onDocumentPicked(Document.fromRoot(getContentResolver(), root)); 548 } catch (FileNotFoundException e) { 549 } 550 } else { 551 onCurrentDirectoryChanged(); 552 } 553 554 if (closeDrawer) { 555 mDrawerLayout.closeDrawers(); 556 } 557 } 558 559 public void onAppPicked(ResolveInfo info) { 560 final Intent intent = new Intent(getIntent()); 561 intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); 562 intent.setComponent(new ComponentName( 563 info.activityInfo.applicationInfo.packageName, info.activityInfo.name)); 564 startActivity(intent); 565 finish(); 566 } 567 568 public void onDocumentPicked(Document doc) { 569 final FragmentManager fm = getFragmentManager(); 570 if (doc.isDirectory()) { 571 // TODO: query display mode user preference for this dir 572 if (doc.isGridPreferred()) { 573 mDisplayState.mode = MODE_GRID; 574 } else { 575 mDisplayState.mode = MODE_LIST; 576 } 577 mStack.push(doc); 578 onCurrentDirectoryChanged(); 579 } else if (mAction == ACTION_OPEN || mAction == ACTION_GET_CONTENT) { 580 // Explicit file picked, return 581 onFinished(doc.uri); 582 } else if (mAction == ACTION_CREATE) { 583 // Replace selected file 584 SaveFragment.get(fm).setReplaceTarget(doc); 585 } else if (mAction == ACTION_MANAGE) { 586 // Open the document 587 // TODO: trampoline activity for launching downloaded APKs 588 final Intent intent = new Intent(Intent.ACTION_VIEW); 589 intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 590 intent.setData(doc.uri); 591 try { 592 startActivity(intent); 593 } catch (ActivityNotFoundException ex) { 594 Toast.makeText(this, R.string.toast_no_application, Toast.LENGTH_SHORT).show(); 595 } 596 } 597 } 598 599 public void onDocumentsPicked(List<Document> docs) { 600 if (mAction == ACTION_OPEN || mAction == ACTION_GET_CONTENT) { 601 final int size = docs.size(); 602 final Uri[] uris = new Uri[size]; 603 for (int i = 0; i < size; i++) { 604 uris[i] = docs.get(i).uri; 605 } 606 onFinished(uris); 607 } 608 } 609 610 public void onSaveRequested(Document replaceTarget) { 611 onFinished(replaceTarget.uri); 612 } 613 614 public void onSaveRequested(String mimeType, String displayName) { 615 final ContentValues values = new ContentValues(); 616 values.put(DocumentColumns.MIME_TYPE, mimeType); 617 values.put(DocumentColumns.DISPLAY_NAME, displayName); 618 619 final Document cwd = getCurrentDirectory(); 620 final Uri childUri = getContentResolver().insert(cwd.uri, values); 621 if (childUri != null) { 622 onFinished(childUri); 623 } else { 624 Toast.makeText(this, R.string.save_error, Toast.LENGTH_SHORT).show(); 625 } 626 } 627 628 private void onFinished(Uri... uris) { 629 Log.d(TAG, "onFinished() " + Arrays.toString(uris)); 630 631 final ContentResolver resolver = getContentResolver(); 632 final ContentValues values = new ContentValues(); 633 634 final String rawStack = DocumentStack.serialize(mStack); 635 if (mAction == ACTION_CREATE) { 636 // Remember stack for last create 637 values.clear(); 638 values.put(RecentsProvider.COL_PATH, rawStack); 639 resolver.insert(RecentsProvider.buildRecentCreate(), values); 640 641 } else if (mAction == ACTION_OPEN || mAction == ACTION_GET_CONTENT) { 642 // Remember opened items 643 for (Uri uri : uris) { 644 values.clear(); 645 values.put(RecentsProvider.COL_URI, uri.toString()); 646 resolver.insert(RecentsProvider.buildRecentOpen(), values); 647 } 648 } 649 650 // Remember location for next app launch 651 final String packageName = getCallingPackage(); 652 values.clear(); 653 values.put(RecentsProvider.COL_PATH, rawStack); 654 resolver.insert(RecentsProvider.buildResume(packageName), values); 655 656 final Intent intent = new Intent(); 657 if (uris.length == 1) { 658 intent.setData(uris[0]); 659 } else if (uris.length > 1) { 660 final ClipData clipData = new ClipData( 661 null, mDisplayState.acceptMimes, new ClipData.Item(uris[0])); 662 for (int i = 1; i < uris.length; i++) { 663 clipData.addItem(new ClipData.Item(uris[i])); 664 } 665 intent.setClipData(clipData); 666 } 667 668 if (mAction == ACTION_GET_CONTENT) { 669 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 670 } else { 671 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION 672 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 673 | Intent.FLAG_PERSIST_GRANT_URI_PERMISSION); 674 } 675 676 setResult(Activity.RESULT_OK, intent); 677 finish(); 678 } 679 680 public static class DisplayState { 681 public int action; 682 public int mode = MODE_LIST; 683 public String[] acceptMimes; 684 public int sortOrder = SORT_ORDER_NAME; 685 public boolean allowMultiple = false; 686 public boolean showSize = false; 687 public boolean localOnly = false; 688 689 public static final int ACTION_OPEN = 1; 690 public static final int ACTION_CREATE = 2; 691 public static final int ACTION_GET_CONTENT = 3; 692 public static final int ACTION_MANAGE = 4; 693 694 public static final int MODE_LIST = 0; 695 public static final int MODE_GRID = 1; 696 697 public static final int SORT_ORDER_NAME = 0; 698 public static final int SORT_ORDER_DATE = 1; 699 public static final int SORT_ORDER_SIZE = 2; 700 } 701 702 private void dumpStack() { 703 Log.d(TAG, "Current stack:"); 704 for (Document doc : mStack) { 705 Log.d(TAG, "--> " + doc); 706 } 707 } 708 709 public static DocumentsActivity get(Fragment fragment) { 710 return (DocumentsActivity) fragment.getActivity(); 711 } 712} 713