OSDN Git Service

Automatically open roots pane if default dir is empty.
authorSteve McKay <smckay@google.com>
Wed, 10 Feb 2016 00:17:24 +0000 (16:17 -0800)
committerSteve McKay <smckay@google.com>
Wed, 10 Feb 2016 00:25:44 +0000 (16:25 -0800)
Move drawer fiddling out of DirectoryFragment into respective
    FragmentTuner instance.

Bug: 27084308
Change-Id: Ia13fc2be1442e1a7164c2d67ea6ce4bcfda68bcc

packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
packages/DocumentsUI/src/com/android/documentsui/State.java
packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java

index 3c21a21..67a5b25 100644 (file)
@@ -216,7 +216,9 @@ public abstract class BaseActivity extends Activity
         return state;
     }
 
-    void onStackRestored(boolean restored, boolean external) {}
+    public void setRootsDrawerOpen(boolean open) {
+        mNavigator.revealRootsDrawer(open);
+    }
 
     void onRootPicked(RootInfo root) {
         // Skip refreshing if root didn't change
index 3485fe4..80bdfda 100644 (file)
@@ -32,7 +32,6 @@ import android.content.ComponentName;
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.ContentValues;
-import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
@@ -141,8 +140,7 @@ public class DocumentsActivity extends BaseActivity {
         }
     }
 
-    @Override
-    void onStackRestored(boolean restored, boolean external) {
+    private void onStackRestored(boolean restored, boolean external) {
         // Show drawer when no stack restored, but only when requesting
         // non-visual content. However, if we last used an external app,
         // drawer is always shown.
@@ -329,10 +327,6 @@ public class DocumentsActivity extends BaseActivity {
         mNavigator.revealRootsDrawer(false);
     }
 
-    public void setRootsDrawerOpen(boolean open) {
-        mNavigator.revealRootsDrawer(open);
-    }
-
     @Override
     public void onDocumentPicked(DocumentInfo doc, SiblingProvider siblings) {
         final FragmentManager fm = getFragmentManager();
index d141de6..bd90eef 100644 (file)
 
 package com.android.documentsui;
 
+import static com.android.documentsui.Shared.DEBUG;
+
 import android.annotation.IntDef;
 import android.content.Intent;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.Log;
 import android.util.SparseArray;
 
 import com.android.documentsui.model.DocumentInfo;
@@ -35,6 +38,8 @@ import java.util.List;
 
 public class State implements android.os.Parcelable {
 
+    private static final String TAG = "State";
+
     public static final int ACTION_OPEN = 1;
     public static final int ACTION_CREATE = 2;
     public static final int ACTION_GET_CONTENT = 3;
@@ -85,6 +90,8 @@ public class State implements android.os.Parcelable {
     /** Current user navigation stack; empty implies recents. */
     public DocumentStack stack = new DocumentStack();
     private boolean mStackTouched;
+    private boolean mInitialRootChanged;
+    private boolean mInitialDocChanged;
 
     /** Currently active search, overriding any stack. */
     public String currentSearch;
@@ -108,22 +115,32 @@ public class State implements android.os.Parcelable {
     }
 
     public void onRootChanged(RootInfo root) {
+        if (DEBUG) Log.d(TAG, "Root changed to: " + root);
+        if (!mInitialRootChanged && stack.root != null && !root.equals(stack.root)) {
+            mInitialRootChanged = true;
+        }
         stack.root = root;
         stack.clear();
         mStackTouched = true;
     }
 
     public void pushDocument(DocumentInfo info) {
+        if (DEBUG) Log.d(TAG, "Adding doc to stack: " + info);
+        if (!mInitialDocChanged && stack.size() > 0 && !info.equals(stack.peek())) {
+            mInitialDocChanged = true;
+        }
         stack.push(info);
         mStackTouched = true;
     }
 
     public void popDocument() {
+        if (DEBUG) Log.d(TAG, "Popping doc off stack.");
         stack.pop();
         mStackTouched = true;
     }
 
     public void setStack(DocumentStack stack) {
+        if (DEBUG) Log.d(TAG, "Setting the whole darn stack to: " + stack);
         this.stack = stack;
         mStackTouched = true;
     }
@@ -132,6 +149,10 @@ public class State implements android.os.Parcelable {
         return mStackTouched;
     }
 
+    public boolean initialiLocationHasChanged() {
+        return mInitialRootChanged || mInitialDocChanged;
+    }
+
     @Override
     public int describeContents() {
         return 0;
@@ -156,6 +177,8 @@ public class State implements android.os.Parcelable {
         out.writeList(excludedAuthorities);
         out.writeInt(openableOnly ? 1 : 0);
         out.writeInt(mStackTouched ? 1 : 0);
+        out.writeInt(mInitialRootChanged ? 1 : 0);
+        out.writeInt(mInitialDocChanged ? 1 : 0);
     }
 
     public static final ClassLoaderCreator<State> CREATOR = new ClassLoaderCreator<State>() {
@@ -184,6 +207,8 @@ public class State implements android.os.Parcelable {
             in.readList(state.excludedAuthorities, loader);
             state.openableOnly = in.readInt() != 0;
             state.mStackTouched = in.readInt() != 0;
+            state.mInitialRootChanged = in.readInt() != 0;
+            state.mInitialDocChanged = in.readInt() != 0;
             return state;
         }
 
index d21b157..ce9fd1b 100644 (file)
@@ -27,6 +27,7 @@ import static com.android.internal.util.Preconditions.checkNotNull;
 import static com.android.internal.util.Preconditions.checkState;
 import static com.google.common.base.Preconditions.checkArgument;
 
+import android.annotation.IntDef;
 import android.annotation.StringRes;
 import android.app.Activity;
 import android.app.ActivityManager;
@@ -100,8 +101,11 @@ import com.android.documentsui.model.DocumentStack;
 import com.android.documentsui.model.RootInfo;
 import com.android.documentsui.services.FileOperationService;
 import com.android.documentsui.services.FileOperations;
+
 import com.google.common.collect.Lists;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -111,6 +115,13 @@ import java.util.List;
  */
 public class DirectoryFragment extends Fragment implements DocumentsAdapter.Environment {
 
+    @IntDef(flag = true, value = {
+            TYPE_NORMAL,
+            TYPE_SEARCH,
+            TYPE_RECENT_OPEN
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ResultType {}
     public static final int TYPE_NORMAL = 1;
     public static final int TYPE_SEARCH = 2;
     public static final int TYPE_RECENT_OPEN = 3;
@@ -147,7 +158,7 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi
     private RecyclerView mRecView;
     private ListeningGestureDetector mGestureDetector;
 
-    private int mType = TYPE_NORMAL;
+    private @ResultType int mType = TYPE_NORMAL;
     private String mStateKey;
 
     private int mLastSortOrder = SORT_ORDER_UNKNOWN;
@@ -262,7 +273,7 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi
         mType = getArguments().getInt(EXTRA_TYPE);
         mStateKey = buildStateKey(root, doc);
 
-        mTuner = FragmentTuner.pick(state);
+        mTuner = FragmentTuner.pick(getContext(), state);
         mClipper = new DocumentClipper(context);
 
         boolean hideGridTitles;
@@ -320,12 +331,6 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi
 
                 updateDisplayState();
 
-                // When launched into empty recents, show drawer
-                if (mType == TYPE_RECENT_OPEN && mModel.isEmpty() && !state.hasLocationChanged() &&
-                        context instanceof DocumentsActivity) {
-                    ((DocumentsActivity) context).setRootsDrawerOpen(true);
-                }
-
                 // Restore any previous instance state
                 final SparseArray<Parcelable> container = state.dirState.remove(mStateKey);
                 if (container != null && !getArguments().getBoolean(EXTRA_IGNORE_STATE, false)) {
@@ -338,6 +343,8 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi
                 }
 
                 mLastSortOrder = state.derivedSortOrder;
+
+                mTuner.onModelLoaded(mModel, mType);
             }
 
             @Override
index a295ab2..3f51e53 100644 (file)
@@ -16,6 +16,7 @@
 
 package com.android.documentsui.dirlist;
 
+import static com.android.documentsui.Shared.DEBUG;
 import static com.android.documentsui.State.ACTION_BROWSE;
 import static com.android.documentsui.State.ACTION_CREATE;
 import static com.android.documentsui.State.ACTION_GET_CONTENT;
@@ -24,36 +25,43 @@ import static com.android.documentsui.State.ACTION_OPEN;
 import static com.android.documentsui.State.ACTION_OPEN_TREE;
 import static com.android.internal.util.Preconditions.checkArgument;
 
-import com.android.documentsui.Menus;
-import com.android.documentsui.MimePredicate;
-import com.android.documentsui.R;
-import com.android.documentsui.State;
-
+import android.content.Context;
 import android.os.SystemProperties;
 import android.provider.DocumentsContract.Document;
+import android.util.Log;
 import android.view.Menu;
 import android.view.MenuItem;
 
+import com.android.documentsui.DocumentsActivity;
+import com.android.documentsui.FilesActivity;
+import com.android.documentsui.Menus;
+import com.android.documentsui.MimePredicate;
+import com.android.documentsui.R;
+import com.android.documentsui.State;
+import com.android.documentsui.dirlist.DirectoryFragment.ResultType;
+
 /**
  * Providers support for specializing the DirectoryFragment to the "host" Activity.
  * Feel free to expand the role of this class to handle other specializations.
  */
 public abstract class FragmentTuner {
 
+    final Context mContext;
     final State mState;
 
-    public FragmentTuner(State state) {
+    public FragmentTuner(Context context, State state) {
+        mContext = context;
         mState = state;
     }
 
-    public static FragmentTuner pick(State state) {
+    public static FragmentTuner pick(Context context, State state) {
         switch (state.action) {
             case ACTION_BROWSE:
-                return new FilesTuner(state);
+                return new FilesTuner(context, state);
             case ACTION_MANAGE:
-                return new DownloadsTuner(state);
+                return new DownloadsTuner(context, state);
             default:
-                return new DocumentsTuner(state);
+                return new DocumentsTuner(context, state);
         }
     }
 
@@ -76,13 +84,15 @@ public abstract class FragmentTuner {
         return MimePredicate.mimeMatches(mState.acceptMimes, docMimeType);
     }
 
+    abstract void onModelLoaded(Model model, @ResultType int resultType);
+
     /**
      * Provides support for Platform specific specializations of DirectoryFragment.
      */
     private static final class DocumentsTuner extends FragmentTuner {
 
-        public DocumentsTuner(State state) {
-            super(state);
+        public DocumentsTuner(Context context, State state) {
+            super(context, state);
         }
 
         @Override
@@ -154,6 +164,16 @@ public abstract class FragmentTuner {
             moveTo.setEnabled(moveEnabled);
             rename.setVisible(false);
         }
+
+        @Override
+        void onModelLoaded(Model model, @ResultType int resultType) {
+            // When launched into empty recents, show drawer
+            if (resultType == DirectoryFragment.TYPE_RECENT_OPEN
+                    && model.isEmpty()
+                    && !mState.hasLocationChanged()) {
+                ((DocumentsActivity) mContext).setRootsDrawerOpen(true);
+            }
+        }
     }
 
     /**
@@ -161,8 +181,8 @@ public abstract class FragmentTuner {
      */
     private static final class DownloadsTuner extends FragmentTuner {
 
-        public DownloadsTuner(State state) {
-            super(state);
+        public DownloadsTuner(Context context, State state) {
+            super(context, state);
         }
 
         @Override
@@ -189,6 +209,9 @@ public abstract class FragmentTuner {
             moveTo.setEnabled(moveEnabled);
             rename.setVisible(false);
         }
+
+        @Override
+        void onModelLoaded(Model model, @ResultType int resultType) {}
     }
 
     /**
@@ -196,8 +219,10 @@ public abstract class FragmentTuner {
      */
     private static final class FilesTuner extends FragmentTuner {
 
-        public FilesTuner(State state) {
-            super(state);
+        private static final String TAG = "FilesTuner";
+
+        public FilesTuner(Context context, State state) {
+            super(context, state);
         }
 
         @Override
@@ -221,9 +246,23 @@ public abstract class FragmentTuner {
 
             Menus.disableHiddenItems(menu, copy, paste);
         }
+
+        @Override
+        void onModelLoaded(Model model, @ResultType int resultType) {
+            if (DEBUG) Log.d(TAG, "Handling model loaded. Has Location shcnage: " + mState.initialiLocationHasChanged());
+            // When launched into empty root, open drawer.
+            if (model.isEmpty() && !mState.initialiLocationHasChanged()) {
+                if (DEBUG) Log.d(TAG, "Showing roots drawer cuz stuffs empty.");
+
+                // This noops on layouts without drawer, so no need to guard.
+                ((FilesActivity) mContext).setRootsDrawerOpen(true);
+            }
+            if (DEBUG) Log.d(TAG, "Donezo.");
+        }
     }
 
     private static boolean isDirectory(String mimeType) {
         return Document.MIME_TYPE_DIR.equals(mimeType);
     }
+
 }