Loading packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java +3 −1 Original line number Diff line number Diff line Loading @@ -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 nor directory didn't change Loading packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java +1 −7 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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(); Loading packages/DocumentsUI/src/com/android/documentsui/State.java +25 −0 Original line number Diff line number Diff line Loading @@ -16,10 +16,13 @@ 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; Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; } Loading @@ -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; Loading @@ -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>() { Loading Loading @@ -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; } Loading packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java +15 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -100,8 +101,11 @@ import com.android.documentsui.model.RootInfo; import com.android.documentsui.services.FileOperationService; import com.android.documentsui.services.FileOperationService.OpType; 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; Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -251,7 +262,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; Loading Loading @@ -309,12 +320,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)) { Loading @@ -327,6 +332,8 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi } mLastSortOrder = state.derivedSortOrder; mTuner.onModelLoaded(mModel, mType); } @Override Loading packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java +55 −16 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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); } } Loading @@ -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 Loading Loading @@ -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); } } } /** Loading @@ -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 Loading @@ -189,6 +209,9 @@ public abstract class FragmentTuner { moveTo.setEnabled(moveEnabled); rename.setVisible(false); } @Override void onModelLoaded(Model model, @ResultType int resultType) {} } /** Loading @@ -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 Loading @@ -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); } } Loading
packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java +3 −1 Original line number Diff line number Diff line Loading @@ -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 nor directory didn't change Loading
packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java +1 −7 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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(); Loading
packages/DocumentsUI/src/com/android/documentsui/State.java +25 −0 Original line number Diff line number Diff line Loading @@ -16,10 +16,13 @@ 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; Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; } Loading @@ -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; Loading @@ -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>() { Loading Loading @@ -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; } Loading
packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java +15 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -100,8 +101,11 @@ import com.android.documentsui.model.RootInfo; import com.android.documentsui.services.FileOperationService; import com.android.documentsui.services.FileOperationService.OpType; 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; Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -251,7 +262,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; Loading Loading @@ -309,12 +320,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)) { Loading @@ -327,6 +332,8 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi } mLastSortOrder = state.derivedSortOrder; mTuner.onModelLoaded(mModel, mType); } @Override Loading
packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java +55 −16 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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); } } Loading @@ -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 Loading Loading @@ -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); } } } /** Loading @@ -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 Loading @@ -189,6 +209,9 @@ public abstract class FragmentTuner { moveTo.setEnabled(moveEnabled); rename.setVisible(false); } @Override void onModelLoaded(Model model, @ResultType int resultType) {} } /** Loading @@ -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 Loading @@ -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); } }