If user ejects a storage from details, take user to...
... the storage list view

1. Change to ExternalStorageProvider
When available volumes have changed, it now notifies on
"content://com.android.externalstorage.documents" rather than on
"content://com.android.externalstorage.documents/root/", because it'll also
affect "content://com.android.externalstorage.documents/document/*/children".

2. Change to DocumentUI
- DirectoryLoader now won't crash when a provider returns null.
- DirectoryFragment now closes itself (i.e. emulate a back press) when a load
failed.
- It now correctly reloads contents when a volume is ejected thanks to 1.

Bug 21472170

Change-Id: Icf4bbc2ebb9067313dbbb67083cd4115b0a75c58
diff --git a/src/com/android/documentsui/DirectoryFragment.java b/src/com/android/documentsui/DirectoryFragment.java
index f4be9c5..006f6e9 100644
--- a/src/com/android/documentsui/DirectoryFragment.java
+++ b/src/com/android/documentsui/DirectoryFragment.java
@@ -50,6 +50,8 @@
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.CancellationSignal;
+import android.os.Handler;
+import android.os.Looper;
 import android.os.OperationCanceledException;
 import android.os.Parcelable;
 import android.provider.DocumentsContract;
@@ -135,6 +137,8 @@
 
     private final int mLoaderId = 42;
 
+    private final Handler mHandler = new Handler(Looper.getMainLooper());
+
     public static void showNormal(FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) {
         show(fm, TYPE_NORMAL, root, doc, null, anim);
     }
@@ -297,6 +301,21 @@
 
             @Override
             public void onLoadFinished(Loader<DirectoryResult> loader, DirectoryResult result) {
+                if (result == null || result.exception != null) {
+                    // onBackPressed does a fragment transaction, which can't be done inside
+                    // onLoadFinished
+                    mHandler.post(new Runnable() {
+                        @Override
+                        public void run() {
+                            final Activity activity = getActivity();
+                            if (activity != null) {
+                                activity.onBackPressed();
+                            }
+                        }
+                    });
+                    return;
+                }
+
                 if (!isAdded()) return;
 
                 mAdapter.swapResult(result);