OSDN Git Service

382b3ff4a6048bf39653786019d8e9d10a90b79b
[android-x86/packages-apps-CMFileManager.git] / src / com / cyanogenmod / filemanager / activities / NavigationActivity.java
1 /*
2  * Copyright (C) 2012 The CyanogenMod 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
17 package com.cyanogenmod.filemanager.activities;
18
19 import android.app.ActionBar;
20 import android.app.Activity;
21 import android.app.AlertDialog;
22 import android.app.SearchManager;
23 import android.content.BroadcastReceiver;
24 import android.content.Context;
25 import android.content.DialogInterface;
26 import android.content.Intent;
27 import android.content.IntentFilter;
28 import android.content.pm.ActivityInfo;
29 import android.os.Bundle;
30 import android.os.Handler;
31 import android.os.Parcelable;
32 import android.os.storage.StorageVolume;
33 import android.util.Log;
34 import android.view.KeyEvent;
35 import android.view.Menu;
36 import android.view.MenuItem;
37 import android.view.View;
38 import android.view.ViewGroup;
39 import android.widget.AdapterView;
40 import android.widget.AdapterView.OnItemClickListener;
41 import android.widget.ListPopupWindow;
42 import android.widget.PopupWindow;
43 import android.widget.Toast;
44
45 import com.cyanogenmod.filemanager.FileManagerApplication;
46 import com.cyanogenmod.filemanager.R;
47 import com.cyanogenmod.filemanager.activities.preferences.SettingsPreferences;
48 import com.cyanogenmod.filemanager.adapters.HighlightedSimpleMenuListAdapter;
49 import com.cyanogenmod.filemanager.adapters.MenuSettingsAdapter;
50 import com.cyanogenmod.filemanager.adapters.SimpleMenuListAdapter;
51 import com.cyanogenmod.filemanager.console.Console;
52 import com.cyanogenmod.filemanager.console.ConsoleAllocException;
53 import com.cyanogenmod.filemanager.console.ConsoleBuilder;
54 import com.cyanogenmod.filemanager.console.NoSuchFileOrDirectory;
55 import com.cyanogenmod.filemanager.listeners.OnHistoryListener;
56 import com.cyanogenmod.filemanager.listeners.OnRequestRefreshListener;
57 import com.cyanogenmod.filemanager.model.DiskUsage;
58 import com.cyanogenmod.filemanager.model.FileSystemObject;
59 import com.cyanogenmod.filemanager.model.History;
60 import com.cyanogenmod.filemanager.model.MountPoint;
61 import com.cyanogenmod.filemanager.parcelables.HistoryNavigable;
62 import com.cyanogenmod.filemanager.parcelables.NavigationViewInfoParcelable;
63 import com.cyanogenmod.filemanager.parcelables.SearchInfoParcelable;
64 import com.cyanogenmod.filemanager.preferences.FileManagerSettings;
65 import com.cyanogenmod.filemanager.preferences.NavigationLayoutMode;
66 import com.cyanogenmod.filemanager.preferences.ObjectIdentifier;
67 import com.cyanogenmod.filemanager.preferences.Preferences;
68 import com.cyanogenmod.filemanager.ui.dialogs.ActionsDialog;
69 import com.cyanogenmod.filemanager.ui.dialogs.FilesystemInfoDialog;
70 import com.cyanogenmod.filemanager.ui.dialogs.FilesystemInfoDialog.OnMountListener;
71 import com.cyanogenmod.filemanager.ui.widgets.Breadcrumb;
72 import com.cyanogenmod.filemanager.ui.widgets.NavigationCustomTitleView;
73 import com.cyanogenmod.filemanager.ui.widgets.NavigationView;
74 import com.cyanogenmod.filemanager.ui.widgets.NavigationView.OnNavigationRequestMenuListener;
75 import com.cyanogenmod.filemanager.ui.widgets.NavigationView.OnNavigationSelectionChangedListener;
76 import com.cyanogenmod.filemanager.ui.widgets.SelectionView;
77 import com.cyanogenmod.filemanager.util.AndroidHelper;
78 import com.cyanogenmod.filemanager.util.CommandHelper;
79 import com.cyanogenmod.filemanager.util.DialogHelper;
80 import com.cyanogenmod.filemanager.util.ExceptionUtil;
81 import com.cyanogenmod.filemanager.util.FileHelper;
82 import com.cyanogenmod.filemanager.util.StorageHelper;
83
84 import java.io.FileNotFoundException;
85 import java.io.Serializable;
86 import java.util.ArrayList;
87 import java.util.Arrays;
88 import java.util.List;
89
90 /**
91  * The main navigation activity. This activity is the center of the application.
92  * From this the user can navigate, search, make actions.<br/>
93  * This activity is singleTop, so when it is displayed no other activities exists in
94  * the stack.<br/>
95  * This cause an issue with the saved instance of this class, because if another activity
96  * is displayed, and the process is killed, NavigationActivity is started and the saved
97  * instance gets corrupted.<br/>
98  * For this reason the methods {link {@link Activity#onSaveInstanceState(Bundle)} and
99  * {@link Activity#onRestoreInstanceState(Bundle)} are not implemented, and every time
100  * the app is killed, is restarted from his initial state.
101  */
102 public class NavigationActivity extends Activity
103     implements OnHistoryListener, OnRequestRefreshListener,
104     OnNavigationRequestMenuListener, OnNavigationSelectionChangedListener {
105
106     private static final String TAG = "NavigationActivity"; //$NON-NLS-1$
107
108     private static boolean DEBUG = false;
109
110     /**
111      * Intent code for request a bookmark selection.
112      */
113     public static final int INTENT_REQUEST_BOOKMARK = 10001;
114
115     /**
116      * Intent code for request a history selection.
117      */
118     public static final int INTENT_REQUEST_HISTORY = 20001;
119
120     /**
121      * Intent code for request a search.
122      */
123     public static final int INTENT_REQUEST_SEARCH = 30001;
124
125
126     /**
127      * Constant for extra information about selected bookmark.
128      */
129     public static final String EXTRA_BOOKMARK_SELECTION =
130             "extra_bookmark_selection"; //$NON-NLS-1$
131
132     /**
133      * Constant for extra information about selected history entry.
134      */
135     public static final String EXTRA_HISTORY_ENTRY_SELECTION =
136             "extra_history_entry_selection"; //$NON-NLS-1$
137
138     /**
139      * Constant for extra information about clear selection action.
140      */
141     public static final String EXTRA_HISTORY_CLEAR =
142             "extra_history_clear_history"; //$NON-NLS-1$
143
144     /**
145      * Constant for extra information about selected search entry.
146      */
147     public static final String EXTRA_SEARCH_ENTRY_SELECTION =
148             "extra_search_entry_selection"; //$NON-NLS-1$
149
150     /**
151      * Constant for extra information about last search data.
152      */
153     public static final String EXTRA_SEARCH_LAST_SEARCH_DATA =
154             "extra_search_last_search_data"; //$NON-NLS-1$
155
156     /**
157      * Constant for extra information for request a navigation to the passed path.
158      */
159     public static final String EXTRA_NAVIGATE_TO =
160             "extra_navigate_to"; //$NON-NLS-1$
161
162     // The timeout needed to reset the exit status for back button
163     // After this time user need to tap 2 times the back button to
164     // exit, and the toast is shown again after the first tap.
165     private static final int RELEASE_EXIT_CHECK_TIMEOUT = 3500;
166
167     private final BroadcastReceiver mOnSettingChangeReceiver = new BroadcastReceiver() {
168         @Override
169         public void onReceive(Context context, Intent intent) {
170             if (intent != null) {
171                 if (intent.getAction().compareTo(FileManagerSettings.INTENT_SETTING_CHANGED) == 0) {
172                     // The settings has changed
173                     String key = intent.getStringExtra(FileManagerSettings.EXTRA_SETTING_CHANGED_KEY);
174                     if (key != null) {
175                         // Disk usage warning level
176                         if (key.compareTo(FileManagerSettings.
177                                 SETTINGS_DISK_USAGE_WARNING_LEVEL.getId()) == 0) {
178
179                             // Set the free disk space warning level of the breadcrumb widget
180                             Breadcrumb breadcrumb = getCurrentNavigationView().getBreadcrumb();
181                             String fds = Preferences.getSharedPreferences().getString(
182                                     FileManagerSettings.SETTINGS_DISK_USAGE_WARNING_LEVEL.getId(),
183                                     (String)FileManagerSettings.
184                                         SETTINGS_DISK_USAGE_WARNING_LEVEL.getDefaultValue());
185                             breadcrumb.setFreeDiskSpaceWarningLevel(Integer.parseInt(fds));
186                             breadcrumb.updateMountPointInfo();
187                             return;
188                         }
189
190                         // Case sensitive sort
191                         if (key.compareTo(FileManagerSettings.
192                                 SETTINGS_CASE_SENSITIVE_SORT.getId()) == 0) {
193                             getCurrentNavigationView().refresh();
194                             return;
195                         }
196
197                         // Advanced mode
198                         if (key.compareTo(FileManagerSettings.
199                                 SETTINGS_ADVANCE_MODE.getId()) == 0) {
200                             // Is it necessary to create or exit of the ChRooted?
201                             boolean chRooted = !FileManagerApplication.isAdvancedMode();
202                             if (chRooted != NavigationActivity.this.mChRooted) {
203                                 if (chRooted) {
204                                     createChRooted();
205                                 } else {
206                                     exitChRooted();
207                                 }
208                             }
209                         }
210                     }
211
212                 } else if (intent.getAction().compareTo(
213                         FileManagerSettings.INTENT_FILE_CHANGED) == 0) {
214                     // Retrieve the file that was changed
215                     String file =
216                             intent.getStringExtra(FileManagerSettings.EXTRA_FILE_CHANGED_KEY);
217                     try {
218                         FileSystemObject fso = CommandHelper.getFileInfo(context, file, null);
219                         if (fso != null) {
220                             getCurrentNavigationView().refresh(fso);
221                         }
222                     } catch (Exception e) {
223                         ExceptionUtil.translateException(context, e, true, false);
224                     }
225                 }
226             }
227         }
228     };
229
230     /**
231      * @hide
232      */
233     NavigationView[] mNavigationViews;
234     private List<History> mHistory;
235
236     private int mCurrentNavigationView;
237
238     private ViewGroup mActionBar;
239     private SelectionView mSelectionBar;
240
241     private boolean mExitFlag = false;
242     private long mExitBackTimeout = -1;
243
244     private View mOptionsAnchorView;
245
246     /**
247      * @hide
248      */
249     boolean mChRooted;
250
251     /**
252      * @hide
253      */
254     Handler mHandler;
255
256     /**
257      * {@inheritDoc}
258      */
259     @Override
260     protected void onCreate(Bundle state) {
261
262         if (DEBUG) {
263             Log.d(TAG, "NavigationActivity.onCreate"); //$NON-NLS-1$
264         }
265
266         // Register the broadcast receiver
267         IntentFilter filter = new IntentFilter();
268         filter.addAction(FileManagerSettings.INTENT_SETTING_CHANGED);
269         filter.addAction(FileManagerSettings.INTENT_FILE_CHANGED);
270         registerReceiver(this.mOnSettingChangeReceiver, filter);
271
272         //Request features
273         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
274
275         //Set the main layout of the activity
276         setContentView(R.layout.navigation);
277
278         // Show welcome message
279         showWelcomeMsg();
280
281         //Initialize activity
282         init();
283
284         //Navigation views
285         initNavigationViews();
286
287         //Initialize action bars
288         initTitleActionBar();
289         initStatusActionBar();
290         initSelectionBar();
291
292         this.mHandler = new Handler();
293         this.mHandler.post(new Runnable() {
294             @Override
295             public void run() {
296                 //Initialize navigation
297                 int cc = NavigationActivity.this.mNavigationViews.length;
298                 for (int i = 0; i < cc; i++) {
299                     initNavigation(i, false);
300                 }
301
302                 //Check the intent action
303                 checkIntent(getIntent());
304             }
305         });
306
307         //Save state
308         super.onCreate(state);
309     }
310
311     /**
312      * {@inheritDoc}
313      */
314     @Override
315     protected void onNewIntent(Intent intent) {
316         //Initialize navigation
317         initNavigation(this.mCurrentNavigationView, true);
318
319         //Check the intent action
320         checkIntent(intent);
321     }
322
323     /**
324      * {@inheritDoc}
325      */
326     @Override
327     protected void onDestroy() {
328         if (DEBUG) {
329             Log.d(TAG, "NavigationActivity.onDestroy"); //$NON-NLS-1$
330         }
331
332         // Unregister the receiver
333         try {
334             unregisterReceiver(this.mOnSettingChangeReceiver);
335         } catch (Throwable ex) {
336             /**NON BLOCK**/
337         }
338
339         //All destroy. Continue
340         super.onDestroy();
341     }
342
343     /**
344      * Method that returns the current navigation view.
345      *
346      * @return NavigationView The current navigation view
347      */
348     public NavigationView getCurrentNavigationView() {
349         return getNavigationView(this.mCurrentNavigationView);
350     }
351
352     /**
353      * Method that returns the current navigation view.
354      *
355      * @param viewId The view to return
356      * @return NavigationView The current navigation view
357      */
358     public NavigationView getNavigationView(int viewId) {
359         return this.mNavigationViews[viewId];
360     }
361
362     /**
363      * Method that initializes the activity.
364      */
365     private void init() {
366         this.mHistory = new ArrayList<History>();
367         this.mChRooted = !FileManagerApplication.isAdvancedMode();
368     }
369
370     /**
371      * Method that displays a welcome message the first time the user
372      * access the application
373      */
374     private void showWelcomeMsg() {
375         boolean firstUse = Preferences.getSharedPreferences().getBoolean(
376                 FileManagerSettings.SETTINGS_FIRST_USE.getId(),
377                 ((Boolean)FileManagerSettings.SETTINGS_FIRST_USE.getDefaultValue()).booleanValue());
378
379         //Display the welcome message?
380         if (firstUse) {
381             AlertDialog dialog = DialogHelper.createAlertDialog(
382                 this, R.drawable.ic_launcher, R.string.welcome_title, R.string.welcome_msg);
383             dialog.show();
384
385             // Don't display again this dialog
386             try {
387                 Preferences.savePreference(
388                         FileManagerSettings.SETTINGS_FIRST_USE, Boolean.FALSE, true);
389             } catch (Exception e) {/**NON BLOCK**/}
390         }
391     }
392
393     /**
394      * Method that initializes the titlebar of the activity.
395      */
396     private void initTitleActionBar() {
397         //Inflate the view and associate breadcrumb
398         NavigationCustomTitleView title =
399                 (NavigationCustomTitleView)getLayoutInflater().inflate(
400                         R.layout.navigation_view_customtitle, null, false);
401         title.setOnHistoryListener(this);
402         Breadcrumb breadcrumb = (Breadcrumb)title.findViewById(R.id.breadcrumb_view);
403         int cc = this.mNavigationViews.length;
404         for (int i = 0; i < cc; i++) {
405             this.mNavigationViews[i].setBreadcrumb(breadcrumb);
406             this.mNavigationViews[i].setOnHistoryListener(this);
407             this.mNavigationViews[i].setOnNavigationSelectionChangedListener(this);
408             this.mNavigationViews[i].setOnNavigationOnRequestMenuListener(this);
409             this.mNavigationViews[i].setCustomTitle(title);
410         }
411
412         // Set the free disk space warning level of the breadcrumb widget
413         String fds = Preferences.getSharedPreferences().getString(
414                 FileManagerSettings.SETTINGS_DISK_USAGE_WARNING_LEVEL.getId(),
415                 (String)FileManagerSettings.SETTINGS_DISK_USAGE_WARNING_LEVEL.getDefaultValue());
416         breadcrumb.setFreeDiskSpaceWarningLevel(Integer.parseInt(fds));
417
418         //Configure the action bar options
419         getActionBar().setBackgroundDrawable(
420                 getResources().getDrawable(R.drawable.bg_holo_titlebar));
421         getActionBar().setDisplayOptions(
422                 ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME);
423         getActionBar().setCustomView(title);
424     }
425
426     /**
427      * Method that initializes the statusbar of the activity.
428      */
429     private void initStatusActionBar() {
430         //Performs a width calculation of buttons. Buttons exceeds the width
431         //of the action bar should be hidden
432         //This application not use android ActionBar because the application
433         //make uses of the title and bottom areas, and wants to force to show
434         //the overflow button (without care of physical buttons)
435         this.mActionBar = (ViewGroup)findViewById(R.id.navigation_actionbar);
436         this.mActionBar.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
437             @Override
438             public void onLayoutChange(
439                     View v, int left, int top, int right, int bottom, int oldLeft,
440                     int oldTop, int oldRight, int oldBottom) {
441                 //Get the width of the action bar
442                 int w = v.getMeasuredWidth();
443
444                 //Wake through children calculation his dimensions
445                 int bw = (int)getResources().getDimension(R.dimen.default_buttom_width);
446                 int cw = 0;
447                 final ViewGroup abView = ((ViewGroup)v);
448                 int cc = abView.getChildCount();
449                 for (int i = 0; i < cc; i++) {
450                     View child = abView.getChildAt(i);
451                     child.setVisibility(cw + bw > w ? View.INVISIBLE : View.VISIBLE);
452                     cw += bw;
453                 }
454             }
455         });
456
457         // Have overflow menu?
458         View overflow = findViewById(R.id.ab_overflow);
459         boolean showOptionsMenu = AndroidHelper.showOptionsMenu(getApplicationContext());
460         overflow.setVisibility(showOptionsMenu ? View.VISIBLE : View.GONE);
461         this.mOptionsAnchorView = showOptionsMenu ? overflow : this.mActionBar;
462     }
463
464     /**
465      * Method that initializes the selectionbar of the activity.
466      */
467     private void initSelectionBar() {
468         this.mSelectionBar = (SelectionView)findViewById(R.id.navigation_selectionbar);
469     }
470
471     /**
472      * Method that initializes the navigation views of the activity
473      */
474     private void initNavigationViews() {
475         //Get the navigation views (wishlist: multiple view; for now only one view)
476         this.mNavigationViews = new NavigationView[1];
477         this.mCurrentNavigationView = 0;
478         //- 0
479         this.mNavigationViews[0] = (NavigationView)findViewById(R.id.navigation_view);
480         this.mNavigationViews[0].setId(0);
481     }
482
483     /**
484      * Method that initializes the navigation.
485      *
486      * @param viewId The navigation view identifier where apply the navigation
487      * @param restore Initialize from a restore info
488      * @hide
489      */
490     void initNavigation(final int viewId, final boolean restore) {
491         final NavigationView navigationView = getNavigationView(viewId);
492         this.mHandler.post(new Runnable() {
493             @Override
494             public void run() {
495                 //Create the default console (from the preferences)
496                 try {
497                     Console console = ConsoleBuilder.getConsole(NavigationActivity.this);
498                     if (console == null) {
499                         throw new ConsoleAllocException("console == null"); //$NON-NLS-1$
500                     }
501                 } catch (Throwable ex) {
502                     if (!NavigationActivity.this.mChRooted) {
503                         //Show exception and exists
504                         Log.e(TAG, getString(R.string.msgs_cant_create_console), ex);
505                         // We don't have any console
506                         // Show exception and exists
507                         DialogHelper.showToast(
508                                 NavigationActivity.this,
509                                 R.string.msgs_cant_create_console, Toast.LENGTH_LONG);
510                         exit();
511                         return;
512                     }
513
514                     // We are in a trouble (something is not allowing creating the console)
515                     // Ask the user to return to advanced console mode with a
516                     // non-privileged console, prior to make crash the application
517                     askOrExit();
518                     return;
519                 }
520
521                 //Is necessary navigate?
522                 if (!restore) {
523                     //Load the preference initial directory
524                     String initialDir =
525                             Preferences.getSharedPreferences().getString(
526                                 FileManagerSettings.SETTINGS_INITIAL_DIR.getId(),
527                                 (String)FileManagerSettings.SETTINGS_INITIAL_DIR.getDefaultValue());
528                     if (NavigationActivity.this.mChRooted) {
529                         // Initial directory is the first external sdcard (sdcard, emmc, usb, ...)
530                         StorageVolume[] volumes =
531                                 StorageHelper.getStorageVolumes(NavigationActivity.this);
532                         if (volumes != null && volumes.length > 0) {
533                             initialDir = volumes[0].getPath();
534                         }
535                     }
536
537                     //Ensure initial is an absolute directory
538                     try {
539                         initialDir =
540                                 CommandHelper.getAbsolutePath(
541                                         NavigationActivity.this, initialDir, null);
542                     } catch (Throwable e) {
543                         Log.e(TAG, "Resolve of initital directory fails", e); //$NON-NLS-1$
544                         String msg =
545                                 getString(
546                                         R.string.msgs_settings_invalid_initial_directory,
547                                         initialDir);
548                         DialogHelper.showToast(NavigationActivity.this, msg, Toast.LENGTH_SHORT);
549                         initialDir = FileHelper.ROOT_DIRECTORY;
550                     }
551
552                     // Change the current directory to the preference initial directory or the
553                     // request if exists
554                     String navigateTo = getIntent().getStringExtra(EXTRA_NAVIGATE_TO);
555                     if (navigateTo != null && navigateTo.length() > 0) {
556                         navigationView.changeCurrentDir(navigateTo);
557                     } else {
558                         navigationView.changeCurrentDir(initialDir);
559                     }
560                 }
561             }
562         });
563     }
564
565     /**
566      * Method that verifies the intent passed to the activity, and checks
567      * if a request is made like Search.
568      *
569      * @param intent The intent to check
570      * @hide
571      */
572     void checkIntent(Intent intent) {
573         //Search action
574         if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
575             Intent searchIntent = new Intent(this, SearchActivity.class);
576             searchIntent.setAction(Intent.ACTION_SEARCH);
577             //- SearchActivity.EXTRA_SEARCH_DIRECTORY
578             searchIntent.putExtra(
579                     SearchActivity.EXTRA_SEARCH_DIRECTORY,
580                     getCurrentNavigationView().getCurrentDir());
581             //- SearchManager.APP_DATA
582             if (intent.getBundleExtra(SearchManager.APP_DATA) != null) {
583                 Bundle bundle = new Bundle();
584                 bundle.putAll(intent.getBundleExtra(SearchManager.APP_DATA));
585                 searchIntent.putExtra(SearchManager.APP_DATA, bundle);
586             }
587             //-- SearchManager.QUERY
588             String query = intent.getStringExtra(SearchManager.QUERY);
589             if (query != null) {
590                 searchIntent.putExtra(SearchManager.QUERY, query);
591             }
592             //- android.speech.RecognizerIntent.EXTRA_RESULTS
593             ArrayList<String> extraResults =
594                     intent.getStringArrayListExtra(android.speech.RecognizerIntent.EXTRA_RESULTS);
595             if (extraResults != null) {
596                 searchIntent.putStringArrayListExtra(
597                         android.speech.RecognizerIntent.EXTRA_RESULTS, extraResults);
598             }
599             startActivityForResult(searchIntent, INTENT_REQUEST_SEARCH);
600             return;
601         }
602
603         // Navigate to the requested path
604         String navigateTo = intent.getStringExtra(EXTRA_NAVIGATE_TO);
605         if (navigateTo != null && navigateTo.length() >= 0) {
606             getCurrentNavigationView().changeCurrentDir(navigateTo);
607         }
608     }
609
610
611     /**
612      * {@inheritDoc}
613      */
614     @Override
615     public boolean onKeyUp(int keyCode, KeyEvent event) {
616         if (keyCode == KeyEvent.KEYCODE_MENU) {
617             showOverflowPopUp(this.mOptionsAnchorView);
618             return true;
619         }
620         if (keyCode == KeyEvent.KEYCODE_BACK) {
621             if (checkBackAction()) {
622                 return true;
623             }
624         }
625         return super.onKeyUp(keyCode, event);
626     }
627
628     /**
629      * {@inheritDoc}
630      */
631     @Override
632     public boolean onOptionsItemSelected(MenuItem item) {
633        switch (item.getItemId()) {
634           case android.R.id.home:
635               if ((getActionBar().getDisplayOptions() & ActionBar.DISPLAY_HOME_AS_UP)
636                       == ActionBar.DISPLAY_HOME_AS_UP) {
637                   checkBackAction();
638               }
639               return true;
640           default:
641              return super.onOptionsItemSelected(item);
642        }
643     }
644
645     /**
646      * Method invoked when an action item is clicked.
647      *
648      * @param view The button pushed
649      */
650     public void onActionBarItemClick(View view) {
651         switch (view.getId()) {
652             //######################
653             //Navigation Custom Title
654             //######################
655             case R.id.ab_configuration:
656                 //Show navigation view configuration toolbar
657                 getCurrentNavigationView().getCustomTitle().showConfigurationView();
658                 getActionBar().setDisplayHomeAsUpEnabled(true);
659                 getActionBar().setHomeButtonEnabled(true);
660                 break;
661             case R.id.ab_close:
662                 //Hide navigation view configuration toolbar
663                 getCurrentNavigationView().getCustomTitle().hideConfigurationView();
664                 break;
665
666             //######################
667             //Breadcrumb Actions
668             //######################
669             case R.id.ab_filesystem_info:
670                 //Show information of the filesystem
671                 MountPoint mp = getCurrentNavigationView().getBreadcrumb().getMountPointInfo();
672                 DiskUsage du = getCurrentNavigationView().getBreadcrumb().getDiskUsageInfo();
673                 showMountPointInfo(mp, du);
674                 break;
675
676             //######################
677             //Navigation view options
678             //######################
679             case R.id.ab_sort_mode:
680                 showSettingsPopUp(view,
681                         Arrays.asList(new FileManagerSettings[]{FileManagerSettings.SETTINGS_SORT_MODE}));
682                 break;
683             case R.id.ab_layout_mode:
684                 showSettingsPopUp(view,
685                         Arrays.asList(
686                                 new FileManagerSettings[]{FileManagerSettings.SETTINGS_LAYOUT_MODE}));
687                 break;
688             case R.id.ab_view_options:
689                 // If we are in ChRooted mode, then don't show non-secure items
690                 if (this.mChRooted) {
691                     showSettingsPopUp(view,
692                             Arrays.asList(new FileManagerSettings[]{
693                                     FileManagerSettings.SETTINGS_SHOW_DIRS_FIRST}));
694                 } else {
695                     showSettingsPopUp(view,
696                             Arrays.asList(new FileManagerSettings[]{
697                                     FileManagerSettings.SETTINGS_SHOW_DIRS_FIRST,
698                                     FileManagerSettings.SETTINGS_SHOW_HIDDEN,
699                                     FileManagerSettings.SETTINGS_SHOW_SYSTEM,
700                                     FileManagerSettings.SETTINGS_SHOW_SYMLINKS}));
701                 }
702
703                 break;
704
705             //######################
706             //Selection Actions
707             //######################
708             case R.id.ab_selection_done:
709                 //Show information of the filesystem
710                 getCurrentNavigationView().onDeselectAll();
711                 break;
712
713             //######################
714             //Action Bar buttons
715             //######################
716             case R.id.ab_actions:
717                 openActionsDialog(getCurrentNavigationView().getCurrentDir(), true);
718                 break;
719
720             case R.id.ab_bookmarks:
721                 openBookmarks();
722                 break;
723
724             case R.id.ab_history:
725                 openHistory();
726                 break;
727
728             case R.id.ab_search:
729                 openSearch();
730                 break;
731
732             case R.id.ab_overflow:
733                 showOverflowPopUp(view);
734                 break;
735
736             default:
737                 break;
738         }
739     }
740
741     /**
742      * {@inheritDoc}
743      */
744     @Override
745     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
746         if (data != null) {
747             switch (requestCode) {
748                 case INTENT_REQUEST_BOOKMARK:
749                     if (resultCode == RESULT_OK) {
750                         FileSystemObject fso =
751                                 (FileSystemObject)data.
752                                     getSerializableExtra(EXTRA_BOOKMARK_SELECTION);
753                         if (fso != null) {
754                             //Open the fso
755                             getCurrentNavigationView().open(fso);
756                         }
757                     }
758                     break;
759
760                 case INTENT_REQUEST_HISTORY:
761                     if (resultCode == RESULT_OK) {
762                         //Change current directory
763                         History history =
764                                 (History)data.getSerializableExtra(EXTRA_HISTORY_ENTRY_SELECTION);
765                         navigateToHistory(history);
766                     } else if (resultCode == RESULT_CANCELED) {
767                         boolean clear = data.getBooleanExtra(EXTRA_HISTORY_CLEAR, false);
768                         if (clear) {
769                             clearHistory();
770                         }
771                     }
772                     break;
773
774                 case INTENT_REQUEST_SEARCH:
775                     if (resultCode == RESULT_OK) {
776                         //Change directory?
777                         FileSystemObject fso =
778                                 (FileSystemObject)data.
779                                     getSerializableExtra(EXTRA_SEARCH_ENTRY_SELECTION);
780                         SearchInfoParcelable searchInfo =
781                                 data.getParcelableExtra(EXTRA_SEARCH_LAST_SEARCH_DATA);
782                         if (fso != null) {
783                             //Goto to new directory
784                             getCurrentNavigationView().open(fso, searchInfo);
785                         }
786                     } else if (resultCode == RESULT_CANCELED) {
787                         SearchInfoParcelable searchInfo =
788                                 data.getParcelableExtra(EXTRA_SEARCH_LAST_SEARCH_DATA);
789                         if (searchInfo != null && searchInfo.isSuccessNavigation()) {
790                             //Navigate to previous history
791                             back();
792                         } else {
793                             // I don't know is the search view was changed, so do a refresh
794                             // of the navigation view
795                             getCurrentNavigationView().refresh();
796                         }
797                     }
798                     break;
799
800                 default:
801                     break;
802             }
803         }
804     }
805
806     /**
807      * {@inheritDoc}
808      */
809     @Override
810     public void onNewHistory(HistoryNavigable navigable) {
811         //Recollect information about current status
812         History history = new History(this.mHistory.size(), navigable);
813         this.mHistory.add(history);
814         getActionBar().setDisplayHomeAsUpEnabled(true);
815         getActionBar().setHomeButtonEnabled(true);
816     }
817
818     /**
819      * {@inheritDoc}
820      */
821     @Override
822     public void onCheckHistory() {
823         //Need to show HomeUp Button
824         boolean enabled = this.mHistory != null && this.mHistory.size() > 0;
825         getActionBar().setDisplayHomeAsUpEnabled(enabled);
826         getActionBar().setHomeButtonEnabled(enabled);
827     }
828
829     /**
830      * {@inheritDoc}
831      */
832     @Override
833     public void onRequestRefresh(Object o) {
834         if (o instanceof FileSystemObject) {
835             // Refresh only the item
836             this.getCurrentNavigationView().refresh((FileSystemObject)o);
837         } else if (o == null) {
838             // Refresh all
839             getCurrentNavigationView().refresh();
840         }
841         this.getCurrentNavigationView().onDeselectAll();
842     }
843
844     /**
845      * {@inheritDoc}
846      */
847     @Override
848     public void onRequestRemove(Object o) {
849         if (o instanceof FileSystemObject) {
850             // Remove from view
851             this.getCurrentNavigationView().removeItem((FileSystemObject)o);
852
853             //Remove from history
854             removeFromHistory((FileSystemObject)o);
855         }
856         this.getCurrentNavigationView().onDeselectAll();
857     }
858
859     /**
860      * {@inheritDoc}
861      */
862     @Override
863     public void onNavigateTo(Object o) {
864         // Ignored
865     }
866
867     /**
868      * {@inheritDoc}
869      */
870     @Override
871     public void onSelectionChanged(NavigationView navView, List<FileSystemObject> selectedItems) {
872         this.mSelectionBar.setSelection(selectedItems);
873     }
874
875     /**
876      * {@inheritDoc}
877      */
878     @Override
879     public void onRequestMenu(NavigationView navView, FileSystemObject item) {
880         // Show the actions dialog
881         openActionsDialog(item, false);
882     }
883
884     /**
885      * Method that shows a popup with a menu associated a {@link FileManagerSettings}.
886      *
887      * @param anchor The action button that was pressed
888      * @param settings The array of settings associated with the action button
889      */
890     private void showSettingsPopUp(View anchor, List<FileManagerSettings> settings) {
891         //Create the adapter
892         final MenuSettingsAdapter adapter = new MenuSettingsAdapter(this, settings);
893
894         //Create a show the popup menu
895         final ListPopupWindow popup = DialogHelper.createListPopupWindow(this, adapter, anchor);
896         popup.setOnItemClickListener(new OnItemClickListener() {
897             @Override
898             public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
899                 FileManagerSettings setting =
900                         ((MenuSettingsAdapter)parent.getAdapter()).getSetting(position);
901                 final int value = ((MenuSettingsAdapter)parent.getAdapter()).getId(position);
902                 popup.dismiss();
903                 try {
904                     if (setting.compareTo(FileManagerSettings.SETTINGS_LAYOUT_MODE) == 0) {
905                         //Need to change the layout
906                         getCurrentNavigationView().changeViewMode(
907                                 NavigationLayoutMode.fromId(value));
908                     } else {
909                         //Save and refresh
910                         if (setting.getDefaultValue() instanceof Enum<?>) {
911                             //Enumeration
912                             Preferences.savePreference(setting, new ObjectIdentifier() {
913                                 @Override
914                                 public int getId() {
915                                     return value;
916                                 }
917                             }, false);
918                         } else {
919                             //Boolean
920                             boolean newval =
921                                     Preferences.getSharedPreferences().
922                                         getBoolean(
923                                             setting.getId(),
924                                             ((Boolean)setting.getDefaultValue()).booleanValue());
925                             Preferences.savePreference(setting, Boolean.valueOf(!newval), false);
926                         }
927                         getCurrentNavigationView().refresh();
928                     }
929                 } catch (Exception e) {
930                     Log.e(TAG, "Error applying navigation option", e); //$NON-NLS-1$
931                     NavigationActivity.this.mHandler.post(new Runnable() {
932                         @Override
933                         public void run() {
934                             DialogHelper.showToast(
935                                     NavigationActivity.this,
936                                     R.string.msgs_settings_save_failure, Toast.LENGTH_SHORT);
937                         }
938                     });
939
940                 } finally {
941                     adapter.dispose();
942                     getCurrentNavigationView().getCustomTitle().restoreView();
943                 }
944
945             }
946         });
947         popup.setOnDismissListener(new PopupWindow.OnDismissListener() {
948             @Override
949             public void onDismiss() {
950                 adapter.dispose();
951             }
952         });
953         popup.show();
954     }
955
956     /**
957      * Method that shows a popup with the activity main menu.
958      *
959      * @param anchor The action button that was pressed
960      */
961     private void showOverflowPopUp(View anchor) {
962         SimpleMenuListAdapter adapter =
963                 new HighlightedSimpleMenuListAdapter(this, R.menu.navigation);
964         Menu menu = adapter.getMenu();
965         int cc = this.mActionBar.getChildCount();
966         for (int i = 0, j = this.mActionBar.getChildCount() - 1; i < cc; i++, j--) {
967             View child = this.mActionBar.getChildAt(i);
968             boolean visible = child.getVisibility() == View.VISIBLE;
969             if (visible) {
970                 menu.removeItem(menu.getItem(j).getItemId());
971             }
972         }
973
974         final ListPopupWindow popup = DialogHelper.createListPopupWindow(this, adapter, anchor);
975         popup.setOnItemClickListener(new OnItemClickListener() {
976             @Override
977             public void onItemClick(
978                     final AdapterView<?> parent, final View v, final int position, final long id) {
979
980                 final int itemId = (int)id;
981                 NavigationActivity.this.mHandler.post(new Runnable() {
982                     @Override
983                     public void run() {
984                         popup.dismiss();
985                         switch (itemId) {
986                             case R.id.mnu_settings:
987                                 //Settings
988                                 Intent settings = new Intent(
989                                         NavigationActivity.this, SettingsPreferences.class);
990                                 startActivity(settings);
991                                 break;
992
993                             case R.id.mnu_history:
994                                 //History
995                                 openHistory();
996                                 popup.dismiss();
997                                 break;
998
999                             case R.id.mnu_bookmarks:
1000                                 //Bookmarks
1001                                 openBookmarks();
1002                                 popup.dismiss();
1003                                 break;
1004
1005                             case R.id.mnu_search:
1006                                 //Search
1007                                 openSearch();
1008                                 popup.dismiss();
1009                                 break;
1010                             default:
1011                                 break;
1012                         }
1013                     }
1014                 });
1015             }
1016         });
1017         popup.show();
1018     }
1019
1020     /**
1021      * Method that show the information of a filesystem mount point.
1022      *
1023      * @param mp The mount point info
1024      * @param du The disk usage of the mount point
1025      */
1026     private void showMountPointInfo(MountPoint mp, DiskUsage du) {
1027         //Has mount point info?
1028         if (mp == null) {
1029             //There is no information
1030             AlertDialog alert =
1031                     DialogHelper.createWarningDialog(this, R.string.filesystem_info_warning_msg);
1032             alert.show();
1033             return;
1034         }
1035
1036         //Show a the filesystem info dialog
1037         FilesystemInfoDialog dialog = new FilesystemInfoDialog(this, mp, du);
1038         dialog.setOnMountListener(new OnMountListener() {
1039             @Override
1040             public void onRemount(MountPoint mountPoint) {
1041                 //Update the statistics of breadcrumb, only if mount point is the same
1042                 Breadcrumb breadcrumb = getCurrentNavigationView().getBreadcrumb();
1043                 if (breadcrumb.getMountPointInfo().compareTo(mountPoint) == 0) {
1044                     breadcrumb.updateMountPointInfo();
1045                 }
1046             }
1047         });
1048         dialog.show();
1049     }
1050
1051     /**
1052      * Method that checks the action that must be realized when the
1053      * back button is pushed.
1054      *
1055      * @return boolean Indicates if the action must be intercepted
1056      */
1057     private boolean checkBackAction() {
1058         //Check if the configuration view is showing. In this case back
1059         //action must be "close configuration"
1060         if (getCurrentNavigationView().getCustomTitle().isConfigurationViewShowing()) {
1061             getCurrentNavigationView().getCustomTitle().restoreView();
1062             return true;
1063         }
1064
1065         //Do back operation over the navigation history
1066         boolean flag = this.mExitFlag;
1067
1068         this.mExitFlag = !back();
1069
1070         // Retrieve if the exit status timeout has expired
1071         long now = System.currentTimeMillis();
1072         boolean timeout = (this.mExitBackTimeout == -1 ||
1073                             (now - this.mExitBackTimeout) > RELEASE_EXIT_CHECK_TIMEOUT);
1074
1075         //Check if there no history and if the user was advised in the last back action
1076         if (this.mExitFlag && (this.mExitFlag != flag || timeout)) {
1077             //Communicate the user that the next time the application will be closed
1078             this.mExitBackTimeout = System.currentTimeMillis();
1079             DialogHelper.showToast(this, R.string.msgs_push_again_to_exit, Toast.LENGTH_SHORT);
1080             return true;
1081         }
1082
1083         //Back action not applied
1084         return !this.mExitFlag;
1085     }
1086
1087     /**
1088      * {@inheritDoc}
1089      */
1090     @Override
1091     public boolean onSearchRequested() {
1092         Bundle bundle = new Bundle();
1093         bundle.putString(
1094                 SearchActivity.EXTRA_SEARCH_DIRECTORY,
1095                 getCurrentNavigationView().getCurrentDir());
1096         // TODO VoiceSearch icon is not shown. This must be a bug of CM. Verify with a test app.
1097         startSearch(Preferences.getLastSearch(), true, bundle, false);
1098         return true;
1099     }
1100
1101     /**
1102      * Method that returns the history size.
1103      */
1104     private void clearHistory() {
1105         this.mHistory.clear();
1106         onCheckHistory();
1107     }
1108
1109     /**
1110      * Method that navigates to the passed history reference.
1111      *
1112      * @param history The history reference
1113      * @return boolean A problem occurs while navigate
1114      */
1115     public boolean navigateToHistory(History history) {
1116         try {
1117             //Gets the history
1118             History realHistory = this.mHistory.get(history.getPosition());
1119
1120             //Navigate to item. Check what kind of history is
1121             if (realHistory.getItem() instanceof NavigationViewInfoParcelable) {
1122                 //Navigation
1123                 NavigationViewInfoParcelable info =
1124                         (NavigationViewInfoParcelable)realHistory.getItem();
1125                 int viewId = info.getId();
1126                 NavigationView view = getNavigationView(viewId);
1127                 view.onRestoreState(info);
1128
1129             } else if (realHistory.getItem() instanceof SearchInfoParcelable) {
1130                 //Search (open search with the search results)
1131                 SearchInfoParcelable info = (SearchInfoParcelable)realHistory.getItem();
1132                 Intent searchIntent = new Intent(this, SearchActivity.class);
1133                 searchIntent.setAction(SearchActivity.ACTION_RESTORE);
1134                 searchIntent.putExtra(SearchActivity.EXTRA_SEARCH_RESTORE, (Parcelable)info);
1135                 startActivityForResult(searchIntent, INTENT_REQUEST_SEARCH);
1136             } else {
1137                 //The type is unknown
1138                 throw new IllegalArgumentException("Unknown history type"); //$NON-NLS-1$
1139             }
1140
1141             //Remove the old history
1142             int cc = realHistory.getPosition();
1143             for (int i = this.mHistory.size() - 1; i >= cc; i--) {
1144                 this.mHistory.remove(i);
1145             }
1146             if (this.mHistory.size() == 0) {
1147                 getActionBar().setDisplayHomeAsUpEnabled(false);
1148                 getActionBar().setHomeButtonEnabled(false);
1149             }
1150
1151             //Navigate
1152             return true;
1153
1154         } catch (Throwable ex) {
1155             if (history != null) {
1156                 Log.e(TAG,
1157                         String.format("Failed to navigate to history %d: %s", //$NON-NLS-1$
1158                                 Integer.valueOf(history.getPosition()),
1159                                 history.getItem().getTitle()), ex);
1160             } else {
1161                 Log.e(TAG,
1162                         String.format("Failed to navigate to history: null", ex)); //$NON-NLS-1$
1163             }
1164             this.mHandler.post(new Runnable() {
1165                 @Override
1166                 public void run() {
1167                     DialogHelper.showToast(
1168                             NavigationActivity.this,
1169                             R.string.msgs_history_unknown, Toast.LENGTH_LONG);
1170                 }
1171             });
1172
1173             //Not change directory
1174             return false;
1175         }
1176     }
1177
1178     /**
1179      * Method that request a back action over the navigation history.
1180      *
1181      * @return boolean If a back action was applied
1182      */
1183     public boolean back() {
1184         // Check that has valid history
1185         while (this.mHistory.size() > 0) {
1186             History h = this.mHistory.get(this.mHistory.size() - 1);
1187             if (h.getItem() instanceof NavigationViewInfoParcelable) {
1188                 // Verify that the path exists
1189                 String path = ((NavigationViewInfoParcelable)h.getItem()).getCurrentDir();
1190
1191                 try {
1192                     FileSystemObject info = CommandHelper.getFileInfo(this, path, null);
1193                     if (info != null) {
1194                         break;
1195                     }
1196                     this.mHistory.remove(this.mHistory.size() - 1);
1197                 } catch (Exception e) {
1198                     ExceptionUtil.translateException(this, e, true, false);
1199                     this.mHistory.remove(this.mHistory.size() - 1);
1200                 }
1201             } else {
1202                 break;
1203             }
1204         }
1205
1206         //Extract a history from the
1207         if (this.mHistory.size() > 0) {
1208             //Navigate to history
1209             return navigateToHistory(this.mHistory.get(this.mHistory.size() - 1));
1210         }
1211
1212         //Nothing to apply
1213         return false;
1214     }
1215
1216     /**
1217      * Method that opens the actions dialog
1218      *
1219      * @param item The path or the {@link FileSystemObject}
1220      * @param global If the menu to display is the one with global actions
1221      */
1222     private void openActionsDialog(Object item, boolean global) {
1223         // Resolve the full path
1224         String path = String.valueOf(item);
1225         if (item instanceof FileSystemObject) {
1226             path = ((FileSystemObject)item).getFullPath();
1227         }
1228
1229         // Prior to show the dialog, refresh the item reference
1230         FileSystemObject fso = null;
1231         try {
1232             fso = CommandHelper.getFileInfo(this, path, false, null);
1233             if (fso == null) {
1234                 throw new NoSuchFileOrDirectory(path);
1235             }
1236
1237         } catch (Exception e) {
1238             // Notify the user
1239             ExceptionUtil.translateException(this, e);
1240
1241             // Remove the object
1242             if (e instanceof FileNotFoundException || e instanceof NoSuchFileOrDirectory) {
1243                 // If have a FileSystemObject reference then there is no need to search
1244                 // the path (less resources used)
1245                 if (item instanceof FileSystemObject) {
1246                     getCurrentNavigationView().removeItem((FileSystemObject)item);
1247                 } else {
1248                     getCurrentNavigationView().removeItem((String)item);
1249                 }
1250             }
1251             return;
1252         }
1253
1254         // Show the dialog
1255         ActionsDialog dialog = new ActionsDialog(this, fso, global, false);
1256         dialog.setOnRequestRefreshListener(this);
1257         dialog.setOnSelectionListener(getCurrentNavigationView());
1258         dialog.show();
1259     }
1260
1261     /**
1262      * Method that opens the bookmarks activity.
1263      * @hide
1264      */
1265     void openBookmarks() {
1266         Intent bookmarksIntent = new Intent(this, BookmarksActivity.class);
1267         bookmarksIntent.addFlags(Intent.FLAG_ACTIVITY_TASK_ON_HOME);
1268         startActivityForResult(bookmarksIntent, INTENT_REQUEST_BOOKMARK);
1269     }
1270
1271     /**
1272      * Method that opens the history activity.
1273      * @hide
1274      */
1275     void openHistory() {
1276         Intent historyIntent = new Intent(this, HistoryActivity.class);
1277         historyIntent.putExtra(HistoryActivity.EXTRA_HISTORY_LIST, (Serializable)this.mHistory);
1278         historyIntent.addFlags(Intent.FLAG_ACTIVITY_TASK_ON_HOME);
1279         startActivityForResult(historyIntent, INTENT_REQUEST_HISTORY);
1280     }
1281
1282     /**
1283      * Method that opens the search activity.
1284      * @hide
1285      */
1286     void openSearch() {
1287         onSearchRequested();
1288     }
1289
1290     /**
1291      * Method that remove the {@link FileSystemObject} from the history
1292      */
1293     private void removeFromHistory(FileSystemObject fso) {
1294         if (this.mHistory != null) {
1295             int cc = this.mHistory.size();
1296             for (int i = cc-1; i >= 0 ; i--) {
1297                 History history = this.mHistory.get(i);
1298                 if (history.getItem() instanceof NavigationViewInfoParcelable) {
1299                     String p0 = fso.getFullPath();
1300                     String p1 =
1301                             ((NavigationViewInfoParcelable)history.getItem()).getCurrentDir();
1302                     if (p0.compareTo(p1) == 0) {
1303                         this.mHistory.remove(i);
1304                     }
1305                 }
1306             }
1307         }
1308     }
1309
1310     /**
1311      * Method that ask the user to change to to advanced console
1312      * @hide
1313      */
1314     void askOrExit() {
1315         //Show a dialog asking the user
1316         AlertDialog dialog =
1317             DialogHelper.createYesNoDialog(
1318                 this, R.string.msgs_change_to_advanced_console_mode,
1319                 new DialogInterface.OnClickListener() {
1320                     @Override
1321                     public void onClick(DialogInterface alertDialog, int which) {
1322                         if (which == DialogInterface.BUTTON_NEGATIVE) {
1323                             // We don't have any console
1324                             // Show exception and exists
1325                             DialogHelper.showToast(
1326                                     NavigationActivity.this,
1327                                     R.string.msgs_cant_create_console, Toast.LENGTH_LONG);
1328                             exit();
1329                             return;
1330                         }
1331
1332                         // Ok. Now try to change to advanced selection console. Any crash
1333                         // here is a fatal error. We won't have any console to operate.
1334                         try {
1335                             // Change console
1336                             ConsoleBuilder.changeToNonPrivilegedConsole(NavigationActivity.this);
1337
1338                             // Save preferences
1339                             Preferences.savePreference(
1340                                     FileManagerSettings.SETTINGS_ADVANCE_MODE,
1341                                     Boolean.TRUE, true);
1342                             Preferences.savePreference(
1343                                     FileManagerSettings.SETTINGS_SUPERUSER_MODE,
1344                                     Boolean.FALSE, true);
1345
1346                         } catch (Exception e) {
1347                             //Show exception and exists
1348                             Log.e(TAG, getString(R.string.msgs_cant_create_console), e);
1349                             DialogHelper.showToast(
1350                                     NavigationActivity.this,
1351                                     R.string.msgs_cant_create_console, Toast.LENGTH_LONG);
1352                             exit();
1353                         }
1354                     }
1355                });
1356         dialog.show();
1357     }
1358
1359     /**
1360      * Method that creates a ChRooted environment, protecting the user to break anything in
1361      * the device
1362      * @hide
1363      */
1364     void createChRooted() {
1365         // If we are in a ChRooted mode, then do nothing
1366         if (this.mChRooted) return;
1367         this.mChRooted = true;
1368
1369         int cc = this.mNavigationViews.length;
1370         for (int i = 0; i < cc; i++) {
1371             this.mNavigationViews[i].createChRooted();
1372         }
1373
1374         // Remove the selection
1375         cc = this.mNavigationViews.length;
1376         for (int i = 0; i < cc; i++) {
1377             getCurrentNavigationView().onDeselectAll();
1378         }
1379
1380         // Remove the history (don't allow to access to previous data)
1381         clearHistory();
1382     }
1383
1384     /**
1385      * Method that exits from a ChRooted
1386      * @hide
1387      */
1388     void exitChRooted() {
1389         // If we aren't in a ChRooted mode, then do nothing
1390         if (!this.mChRooted) return;
1391         this.mChRooted = false;
1392
1393         int cc = this.mNavigationViews.length;
1394         for (int i = 0; i < cc; i++) {
1395             this.mNavigationViews[i].exitChRooted();
1396         }
1397     }
1398
1399     /**
1400      * Method called when a controlled exit is required
1401      * @hide
1402      */
1403     void exit() {
1404         try {
1405             FileManagerApplication.destroyBackgroundConsole();
1406         } catch (Throwable ex) {
1407             /**NON BLOCK**/
1408         }
1409         try {
1410             ConsoleBuilder.destroyConsole();
1411         } catch (Throwable ex) {
1412             /**NON BLOCK**/
1413         }
1414         finish();
1415     }
1416
1417 }