diff options
| author | 2015-09-08 07:31:19 -0700 | |
|---|---|---|
| committer | 2015-09-11 13:58:41 -0700 | |
| commit | 0f7078f0045f354ba6573f0094e097a9afd6534d (patch) | |
| tree | 8812ac75c53bb4064ed072a5787c3b23861e70ca | |
| parent | 18fce3cd3ccef83b3a26e34b1eb2161e0e957118 (diff) | |
Refactor DocsUI to break out a new ManageRootActivity.
- Split all ACTION_MANAGE-related functionality off from
DocumentsActivity, into a new activity.
- Create new full-screen layouts for said activity.
- Fix some styling issues in {Documents,Files}Activity.
Change-Id: I0384715ad3c7d70a3a3daf510f1a09e8c5732348
14 files changed, 439 insertions, 158 deletions
diff --git a/packages/DocumentsUI/AndroidManifest.xml b/packages/DocumentsUI/AndroidManifest.xml index d57876922a07..97bc8fd4d1f4 100644 --- a/packages/DocumentsUI/AndroidManifest.xml +++ b/packages/DocumentsUI/AndroidManifest.xml @@ -36,12 +36,18 @@ <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <intent-filter> - <action android:name="android.provider.action.MANAGE_ROOT" /> + <action android:name="android.provider.action.BROWSE_DOCUMENT_ROOT" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="vnd.android.document/root" /> </intent-filter> + </activity> + + <activity + android:name=".ManageRootActivity" + android:theme="@style/DocumentsNonDialogTheme" + android:icon="@drawable/ic_doc_text"> <intent-filter> - <action android:name="android.provider.action.BROWSE_DOCUMENT_ROOT" /> + <action android:name="android.provider.action.MANAGE_ROOT" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="vnd.android.document/root" /> </intent-filter> diff --git a/packages/DocumentsUI/res/layout/directory_cluster.xml b/packages/DocumentsUI/res/layout/directory_cluster.xml new file mode 100644 index 000000000000..e47e1960563c --- /dev/null +++ b/packages/DocumentsUI/res/layout/directory_cluster.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2013 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <com.android.documentsui.DirectoryContainerView + android:id="@+id/container_directory" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" /> + + <FrameLayout + android:id="@+id/container_save" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@color/material_grey_50" + android:elevation="8dp" /> + +</LinearLayout> diff --git a/packages/DocumentsUI/res/layout/drawer_layout.xml b/packages/DocumentsUI/res/layout/drawer_layout.xml index 32431e3a3f78..dec4e923e6ec 100644 --- a/packages/DocumentsUI/res/layout/drawer_layout.xml +++ b/packages/DocumentsUI/res/layout/drawer_layout.xml @@ -30,7 +30,8 @@ android:layout_height="?android:attr/actionBarSize" android:background="?android:attr/colorPrimary" android:elevation="8dp" - android:theme="?android:attr/actionBarTheme"> + android:theme="?actionBarTheme" + android:popupTheme="?actionBarPopupTheme"> <Spinner android:id="@+id/stack" @@ -41,18 +42,7 @@ </com.android.documentsui.DocumentsToolBar> - <com.android.documentsui.DirectoryContainerView - android:id="@+id/container_directory" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1" /> - - <FrameLayout - android:id="@+id/container_save" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:background="@color/material_grey_50" - android:elevation="8dp" /> + <include layout="@layout/directory_cluster"/> </LinearLayout> @@ -71,7 +61,8 @@ android:layout_height="?android:attr/actionBarSize" android:background="?android:attr/colorPrimary" android:elevation="8dp" - android:theme="?android:attr/actionBarTheme" /> + android:theme="?actionBarTheme" + android:popupTheme="?actionBarPopupTheme" /> <FrameLayout android:id="@+id/container_roots" diff --git a/packages/DocumentsUI/res/layout/fixed_layout.xml b/packages/DocumentsUI/res/layout/fixed_layout.xml index 9769f26339f8..eba9af4297f7 100644 --- a/packages/DocumentsUI/res/layout/fixed_layout.xml +++ b/packages/DocumentsUI/res/layout/fixed_layout.xml @@ -51,28 +51,11 @@ android:layout_width="256dp" android:layout_height="match_parent" /> - <LinearLayout + <include layout="@layout/directory_cluster" android:layout_width="0dp" - android:layout_height="match_parent" android:layout_weight="1" - android:orientation="vertical" - android:background="@color/material_grey_50" - android:elevation="8dp"> - - <com.android.documentsui.DirectoryContainerView - android:id="@+id/container_directory" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1" /> - - <FrameLayout - android:id="@+id/container_save" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:background="@color/material_grey_50" - android:elevation="8dp" /> - - </LinearLayout> + android:elevation="8dp" + android:background="@color/material_grey_50" /> </LinearLayout> diff --git a/packages/DocumentsUI/res/layout/single_pane_layout.xml b/packages/DocumentsUI/res/layout/single_pane_layout.xml new file mode 100644 index 000000000000..20c3232c9686 --- /dev/null +++ b/packages/DocumentsUI/res/layout/single_pane_layout.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2013 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <com.android.documentsui.DocumentsToolBar + android:id="@+id/toolbar" + android:layout_width="match_parent" + android:layout_height="?android:attr/actionBarSize" + android:background="?android:attr/colorPrimary" + android:elevation="8dp" + android:theme="?actionBarTheme" + android:popupTheme="?actionBarPopupTheme"> + + <Spinner + android:id="@+id/stack" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="4dp" + android:overlapAnchor="true" /> + + </com.android.documentsui.DocumentsToolBar> + + <include layout="@layout/directory_cluster"/> + +</LinearLayout> diff --git a/packages/DocumentsUI/res/menu/activity.xml b/packages/DocumentsUI/res/menu/activity.xml index e1f6562bbd82..7df152fb9775 100644 --- a/packages/DocumentsUI/res/menu/activity.xml +++ b/packages/DocumentsUI/res/menu/activity.xml @@ -26,7 +26,8 @@ android:id="@+id/menu_create_dir" android:title="@string/menu_create_dir" android:icon="@drawable/ic_menu_new_folder" - android:showAsAction="always" /> + android:showAsAction="always" + android:visible="false" /> <item android:id="@+id/menu_sort" android:title="@string/menu_sort" @@ -62,10 +63,12 @@ android:visible="false" /> <item android:id="@+id/menu_advanced" - android:showAsAction="never" /> + android:showAsAction="never" + android:visible="false" /> <item android:id="@+id/menu_file_size" - android:showAsAction="never" /> + android:showAsAction="never" + android:visible="false" /> <item android:id="@+id/menu_settings" android:title="@string/menu_settings" diff --git a/packages/DocumentsUI/res/values/layouts.xml b/packages/DocumentsUI/res/values/layouts.xml index c73a1cbf2538..8ac1ac2bbbfc 100644 --- a/packages/DocumentsUI/res/values/layouts.xml +++ b/packages/DocumentsUI/res/values/layouts.xml @@ -17,4 +17,5 @@ <resources> <item name="docs_activity" type="layout">@layout/drawer_layout</item> <item name="files_activity" type="layout">@layout/drawer_layout</item> + <item name="manage_roots_activity" type="layout">@layout/single_pane_layout</item> </resources> diff --git a/packages/DocumentsUI/res/values/styles.xml b/packages/DocumentsUI/res/values/styles.xml index 22add986febb..e67f956112ce 100644 --- a/packages/DocumentsUI/res/values/styles.xml +++ b/packages/DocumentsUI/res/values/styles.xml @@ -57,6 +57,10 @@ <item name="android:colorPrimaryDark">@color/primary_dark</item> <item name="android:colorPrimary">@color/primary</item> <item name="android:colorAccent">@color/accent</item> + + <item name="android:actionModeStyle">@style/ActionModeStyle</item> + + <item name="android:alertDialogTheme">@style/AlertDialogTheme</item> </style> <style name="ActionModeStyle" parent="@android:style/Widget.Material.Light.ActionMode"> diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java index 2835106b9a87..1e7a42fa7732 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java @@ -16,6 +16,13 @@ package com.android.documentsui; +import static com.android.documentsui.BaseActivity.State.ACTION_BROWSE; +import static com.android.documentsui.BaseActivity.State.ACTION_CREATE; +import static com.android.documentsui.BaseActivity.State.ACTION_GET_CONTENT; +import static com.android.documentsui.BaseActivity.State.ACTION_MANAGE; +import static com.android.documentsui.BaseActivity.State.ACTION_OPEN; +import static com.android.documentsui.BaseActivity.State.ACTION_OPEN_COPY_DESTINATION; +import static com.android.documentsui.BaseActivity.State.ACTION_OPEN_TREE; import static com.android.documentsui.DirectoryFragment.ANIM_DOWN; import static com.android.documentsui.DirectoryFragment.ANIM_NONE; import static com.android.documentsui.DirectoryFragment.ANIM_SIDE; @@ -47,7 +54,6 @@ import android.view.MenuItem; import android.view.MenuItem.OnActionExpandListener; import android.view.View; import android.view.ViewGroup; -import android.view.ViewStub; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.BaseAdapter; @@ -85,7 +91,6 @@ abstract class BaseActivity extends Activity { private int mLayoutId; private final String mTag; - public abstract State getDisplayState(); public abstract void onDocumentPicked(DocumentInfo doc, @Nullable DocumentContext siblings); public abstract void onDocumentsPicked(List<DocumentInfo> docs); @@ -93,7 +98,7 @@ abstract class BaseActivity extends Activity { abstract void onDirectoryChanged(int anim); abstract void updateActionBar(); abstract void saveStackBlocking(); - abstract State buildDefaultState(); + abstract State buildState(); public BaseActivity(@LayoutRes int layoutId, String tag) { mLayoutId = layoutId; @@ -106,7 +111,7 @@ abstract class BaseActivity extends Activity { mState = (icicle != null) ? icicle.<State>getParcelable(EXTRA_STATE) - : buildDefaultState(); + : buildState(); setContentView(mLayoutId); @@ -154,30 +159,46 @@ abstract class BaseActivity extends Activity { final MenuItem sortSize = menu.findItem(R.id.menu_sort_size); final MenuItem grid = menu.findItem(R.id.menu_grid); final MenuItem list = menu.findItem(R.id.menu_list); - final MenuItem advanced = menu.findItem(R.id.menu_advanced); final MenuItem fileSize = menu.findItem(R.id.menu_file_size); + final MenuItem settings = menu.findItem(R.id.menu_settings); mSearchManager.update(root); // Search uses backend ranking; no sorting sort.setVisible(cwd != null && !mSearchManager.isSearching()); - State state = getDisplayState(); - grid.setVisible(state.derivedMode != State.MODE_GRID); - list.setVisible(state.derivedMode != State.MODE_LIST); - - // Only sort by size when visible - sortSize.setVisible(state.showSize); - advanced.setTitle(LocalPreferences.getDisplayAdvancedDevices(this) ? R.string.menu_advanced_hide : R.string.menu_advanced_show); fileSize.setTitle(LocalPreferences.getDisplayFileSize(this) ? R.string.menu_file_size_hide : R.string.menu_file_size_show); + State state = getDisplayState(); + + sortSize.setVisible(state.showSize); // Only sort by size when visible + grid.setVisible(state.derivedMode != State.MODE_GRID); + list.setVisible(state.derivedMode != State.MODE_LIST); + settings.setVisible((root.flags & Root.FLAG_HAS_SETTINGS) != 0); + return shown; } + State buildDefaultState() { + State state = new State(); + + final Intent intent = getIntent(); + final String action = intent.getAction(); + + state.localOnly = intent.getBooleanExtra(Intent.EXTRA_LOCAL_ONLY, false); + state.forceAdvanced = intent.getBooleanExtra(DocumentsContract.EXTRA_SHOW_ADVANCED, false); + state.showAdvanced = state.forceAdvanced || + LocalPreferences.getDisplayAdvancedDevices(this); + + state.excludedAuthorities = getExcludedAuthorities(); + + return state; + } + void onStackRestored(boolean restored, boolean external) {} void onRootPicked(RootInfo root) { @@ -344,6 +365,10 @@ abstract class BaseActivity extends Activity { return (BaseActivity) fragment.getActivity(); } + public State getDisplayState() { + return mState; + } + public static abstract class DocumentsIntent { /** Intent action name to open copy destination. */ public static String ACTION_OPEN_COPY_DESTINATION = @@ -664,6 +689,33 @@ abstract class BaseActivity extends Activity { } } + final class RestoreRootTask extends AsyncTask<Void, Void, RootInfo> { + private Uri mRootUri; + + public RestoreRootTask(Uri rootUri) { + mRootUri = rootUri; + } + + @Override + protected RootInfo doInBackground(Void... params) { + final String rootId = DocumentsContract.getRootId(mRootUri); + return mRoots.getRootOneshot(mRootUri.getAuthority(), rootId); + } + + @Override + protected void onPostExecute(RootInfo root) { + if (isDestroyed()) return; + mState.restored = true; + + if (root != null) { + onRootPicked(root); + } else { + Log.w(mTag, "Failed to find root: " + mRootUri); + finish(); + } + } + } + final class ItemSelectedListener implements OnItemSelectedListener { boolean mIgnoreNextNavigation; diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java index 93921dd51490..4ce404b2d3ea 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java @@ -77,6 +77,7 @@ import android.text.format.Time; import android.util.Log; import android.util.SparseArray; import android.util.SparseBooleanArray; +import android.util.TypedValue; import android.view.ActionMode; import android.view.DragEvent; import android.view.GestureDetector; @@ -650,8 +651,12 @@ public class DirectoryFragment extends Fragment { if (mActionMode != null) { mActionMode.finish(); } - getActivity().getWindow().setStatusBarColor( - getResources().getColor(R.color.status_bar_background)); + // Obtain the original status bar color from the theme, and restore it. + TypedValue color = new TypedValue(); + getActivity().getTheme().resolveAttribute( + android.R.attr.colorPrimaryDark, color, true); + getActivity().getWindow().setStatusBarColor(color.data); + } if (mActionMode != null) { diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java index fdc4bb06ffff..1de1c6a57028 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java @@ -19,7 +19,6 @@ package com.android.documentsui; import static com.android.documentsui.BaseActivity.State.ACTION_BROWSE; import static com.android.documentsui.BaseActivity.State.ACTION_CREATE; import static com.android.documentsui.BaseActivity.State.ACTION_GET_CONTENT; -import static com.android.documentsui.BaseActivity.State.ACTION_MANAGE; import static com.android.documentsui.BaseActivity.State.ACTION_OPEN; import static com.android.documentsui.BaseActivity.State.ACTION_OPEN_COPY_DESTINATION; import static com.android.documentsui.BaseActivity.State.ACTION_OPEN_TREE; @@ -67,7 +66,7 @@ import java.util.List; public class DocumentsActivity extends BaseActivity { private static final int CODE_FORWARD = 42; - public static final String TAG = "Documents"; + private static final String TAG = "DocumentsActivity"; private boolean mShowAsDialog; @@ -90,8 +89,7 @@ public class DocumentsActivity extends BaseActivity { super.onCreate(icicle); final Resources res = getResources(); - mShowAsDialog = res.getBoolean(R.bool.show_as_dialog) && mState.action != ACTION_MANAGE && - mState.action != ACTION_BROWSE; + mShowAsDialog = res.getBoolean(R.bool.show_as_dialog) && mState.action != ACTION_BROWSE; if (!mShowAsDialog) { setTheme(R.style.DocumentsNonDialogTheme); @@ -119,8 +117,6 @@ public class DocumentsActivity extends BaseActivity { mDirectoryContainer = (DirectoryContainerView) findViewById(R.id.container_directory); mToolbar = (Toolbar) findViewById(R.id.toolbar); - mToolbar.setTitleTextAppearance(context, - android.R.style.TextAppearance_DeviceDefault_Widget_ActionBar_Title); mStackAdapter = new StackAdapter(); mStackListener = new ItemSelectedListener(); @@ -128,15 +124,11 @@ public class DocumentsActivity extends BaseActivity { mToolbarStack.setOnItemSelectedListener(mStackListener); mRootsToolbar = (Toolbar) findViewById(R.id.roots_toolbar); - if (mRootsToolbar != null) { - mRootsToolbar.setTitleTextAppearance(context, - android.R.style.TextAppearance_DeviceDefault_Widget_ActionBar_Title); - } setActionBar(mToolbar); // Hide roots when we're managing a specific root - if (mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE) { + if (mState.action == ACTION_BROWSE) { mDrawer.lockClosed(); if (mShowAsDialog) { findViewById(R.id.container_roots).setVisibility(View.GONE); @@ -168,7 +160,7 @@ public class DocumentsActivity extends BaseActivity { // In this case, we set the activity title in AsyncTask.onPostExecute(). To prevent // talkback from reading aloud the default title, we clear it here. setTitle(""); - if (mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE) { + if (mState.action == ACTION_BROWSE) { final Uri rootUri = getIntent().getData(); new RestoreRootTask(rootUri).executeOnExecutor(getCurrentExecutor()); } else { @@ -180,8 +172,8 @@ public class DocumentsActivity extends BaseActivity { } @Override - State buildDefaultState() { - State state = new State(); + State buildState() { + State state = buildDefaultState(); final Intent intent = getIntent(); final String action = intent.getAction(); @@ -193,8 +185,6 @@ public class DocumentsActivity extends BaseActivity { state.action = ACTION_GET_CONTENT; } else if (Intent.ACTION_OPEN_DOCUMENT_TREE.equals(action)) { state.action = ACTION_OPEN_TREE; - } else if (DocumentsContract.ACTION_MANAGE_ROOT.equals(action)) { - state.action = ACTION_MANAGE; } else if (DocumentsContract.ACTION_BROWSE_DOCUMENT_ROOT.equals(action)) { state.action = ACTION_BROWSE; } else if (DocumentsIntent.ACTION_OPEN_COPY_DESTINATION.equals(action)) { @@ -206,7 +196,7 @@ public class DocumentsActivity extends BaseActivity { Intent.EXTRA_ALLOW_MULTIPLE, false); } - if (state.action == ACTION_MANAGE || state.action == ACTION_BROWSE) { + if (state.action == ACTION_BROWSE) { state.acceptMimes = new String[] { "*/*" }; state.allowMultiple = true; } else if (intent.hasExtra(Intent.EXTRA_MIME_TYPES)) { @@ -215,12 +205,7 @@ public class DocumentsActivity extends BaseActivity { state.acceptMimes = new String[] { intent.getType() }; } - state.localOnly = intent.getBooleanExtra(Intent.EXTRA_LOCAL_ONLY, false); - state.forceAdvanced = intent.getBooleanExtra(DocumentsContract.EXTRA_SHOW_ADVANCED, false); - state.showAdvanced = state.forceAdvanced - | LocalPreferences.getDisplayAdvancedDevices(this); - - if (state.action == ACTION_MANAGE || state.action == ACTION_BROWSE) { + if (state.action == ACTION_BROWSE) { state.showSize = true; } else { state.showSize = LocalPreferences.getDisplayFileSize(this); @@ -232,38 +217,9 @@ public class DocumentsActivity extends BaseActivity { CopyService.TRANSFER_MODE_NONE); } - state.excludedAuthorities = getExcludedAuthorities(); - return state; } - private class RestoreRootTask extends AsyncTask<Void, Void, RootInfo> { - private Uri mRootUri; - - public RestoreRootTask(Uri rootUri) { - mRootUri = rootUri; - } - - @Override - protected RootInfo doInBackground(Void... params) { - final String rootId = DocumentsContract.getRootId(mRootUri); - return mRoots.getRootOneshot(mRootUri.getAuthority(), rootId); - } - - @Override - protected void onPostExecute(RootInfo root) { - if (isDestroyed()) return; - mState.restored = true; - - if (root != null) { - onRootPicked(root); - } else { - Log.w(TAG, "Failed to find root: " + mRootUri); - finish(); - } - } - } - @Override void onStackRestored(boolean restored, boolean external) { // Show drawer when no stack restored, but only when requesting @@ -405,8 +361,11 @@ public class DocumentsActivity extends BaseActivity { final MenuItem fileSize = menu.findItem(R.id.menu_file_size); final MenuItem settings = menu.findItem(R.id.menu_settings); - boolean fileSizeVisible = !(mState.action == ACTION_MANAGE - || mState.action == ACTION_BROWSE); + // File size is locked visible for browse because that is the action triggered by Settings, + // where the user is trying to find large files to clean up. + // TODO: instead of setting this according to the action, use a local preference, but + // provide a @hide extra to let callers like Settings force-enable size visibility. + boolean fileSizeVisible = mState.action != ACTION_BROWSE; if (mState.action == ACTION_CREATE || mState.action == ACTION_OPEN_TREE || mState.action == ACTION_OPEN_COPY_DESTINATION) { @@ -428,11 +387,10 @@ public class DocumentsActivity extends BaseActivity { createDir.setVisible(false); } - advanced.setVisible(!(mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE) && - !mState.forceAdvanced); + advanced.setVisible(mState.action != ACTION_BROWSE && !mState.forceAdvanced); fileSize.setVisible(fileSizeVisible); - settings.setVisible((mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE) + settings.setVisible(mState.action == ACTION_BROWSE && (root.flags & Root.FLAG_HAS_SETTINGS) != 0); return true; @@ -444,11 +402,6 @@ public class DocumentsActivity extends BaseActivity { } @Override - public State getDisplayState() { - return mState; - } - - @Override void onDirectoryChanged(int anim) { final FragmentManager fm = getFragmentManager(); final RootInfo root = getCurrentRoot(); @@ -523,26 +476,6 @@ public class DocumentsActivity extends BaseActivity { } else if (mState.action == ACTION_CREATE) { // Replace selected file SaveFragment.get(fm).setReplaceTarget(doc); - } else if (mState.action == ACTION_MANAGE) { - // First try managing the document; we expect manager to filter - // based on authority, so we don't grant. - final Intent manage = new Intent(DocumentsContract.ACTION_MANAGE_DOCUMENT); - manage.setData(doc.derivedUri); - - try { - startActivity(manage); - } catch (ActivityNotFoundException ex) { - // Fall back to viewing - final Intent view = new Intent(Intent.ACTION_VIEW); - view.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - view.setData(doc.derivedUri); - - try { - startActivity(view); - } catch (ActivityNotFoundException ex2) { - Toast.makeText(this, R.string.toast_no_application, Toast.LENGTH_SHORT).show(); - } - } } else if (mState.action == ACTION_BROWSE) { // Go straight to viewing final Intent view = new Intent(Intent.ACTION_VIEW); diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java index 7c445bf79ee1..8f9025a1cdeb 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java @@ -30,7 +30,6 @@ import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.provider.DocumentsContract; -import android.provider.DocumentsContract.Root; import android.support.annotation.Nullable; import android.util.Log; import android.view.KeyEvent; @@ -58,12 +57,11 @@ import java.util.List; */ public class FilesActivity extends BaseActivity { - public static final String TAG = "StandaloneFileManagement"; + public static final String TAG = "FilesActivity"; static final boolean DEBUG = false; private Toolbar mToolbar; private Spinner mToolbarStack; - private Toolbar mRootsToolbar; private DirectoryContainerView mDirectoryContainer; private ItemSelectedListener mStackListener; private BaseAdapter mStackAdapter; @@ -82,20 +80,12 @@ public class FilesActivity extends BaseActivity { mDirectoryContainer = (DirectoryContainerView) findViewById(R.id.container_directory); mToolbar = (Toolbar) findViewById(R.id.toolbar); - mToolbar.setTitleTextAppearance(context, - android.R.style.TextAppearance_DeviceDefault_Widget_ActionBar_Title); mStackAdapter = new StackAdapter(); mStackListener = new ItemSelectedListener(); mToolbarStack = (Spinner) findViewById(R.id.stack); mToolbarStack.setOnItemSelectedListener(mStackListener); - mRootsToolbar = (Toolbar) findViewById(R.id.roots_toolbar); - if (mRootsToolbar != null) { - mRootsToolbar.setTitleTextAppearance(context, - android.R.style.TextAppearance_DeviceDefault_Widget_ActionBar_Title); - } - setActionBar(mToolbar); mClipper = new DocumentClipper(this); @@ -127,14 +117,14 @@ public class FilesActivity extends BaseActivity { } @Override - State buildDefaultState() { - State state = new State(); + State buildState() { + State state = buildDefaultState(); final Intent intent = getIntent(); + state.action = State.ACTION_BROWSE_ALL; - state.acceptMimes = new String[] { "*/*" }; - state.allowMultiple = true; state.acceptMimes = new String[] { intent.getType() }; + state.allowMultiple = true; // These options are specific to the DocumentsActivity. Preconditions.checkArgument( @@ -223,8 +213,6 @@ public class FilesActivity extends BaseActivity { createDir.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); createDir.setVisible(canCreateDir); - settings.setVisible((getCurrentRoot().flags & Root.FLAG_HAS_SETTINGS) != 0); - pasteFromCb.setVisible(true); pasteFromCb.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); pasteFromCb.setEnabled(mClipper.hasItemsToPaste()); @@ -246,11 +234,6 @@ public class FilesActivity extends BaseActivity { } @Override - public State getDisplayState() { - return mState; - } - - @Override void onDirectoryChanged(int anim) { final FragmentManager fm = getFragmentManager(); final RootInfo root = getCurrentRoot(); diff --git a/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java b/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java index 99592659a7fb..ec1cb1de5c57 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java +++ b/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java @@ -222,7 +222,7 @@ public class IconUtils { return context.getDrawable(R.drawable.ic_doc_album); } - if (mode == DocumentsActivity.State.MODE_GRID) { + if (mode == BaseActivity.State.MODE_GRID) { return context.getDrawable(R.drawable.ic_grid_folder); } else { return context.getDrawable(R.drawable.ic_doc_folder); diff --git a/packages/DocumentsUI/src/com/android/documentsui/ManageRootActivity.java b/packages/DocumentsUI/src/com/android/documentsui/ManageRootActivity.java new file mode 100644 index 000000000000..740157829d3f --- /dev/null +++ b/packages/DocumentsUI/src/com/android/documentsui/ManageRootActivity.java @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.documentsui; + +import static com.android.documentsui.BaseActivity.State.ACTION_MANAGE; +import static com.android.documentsui.DirectoryFragment.ANIM_DOWN; +import static com.android.documentsui.DirectoryFragment.ANIM_NONE; + +import android.app.Activity; +import android.app.Fragment; +import android.app.FragmentManager; +import android.content.ActivityNotFoundException; +import android.content.ClipData; +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.provider.DocumentsContract; +import android.util.Log; +import android.view.Menu; +import android.view.View; +import android.widget.BaseAdapter; +import android.widget.Spinner; +import android.widget.Toast; +import android.widget.Toolbar; + +import com.android.documentsui.RecentsProvider.ResumeColumns; +import com.android.documentsui.model.DocumentInfo; +import com.android.documentsui.model.DurableUtils; +import com.android.documentsui.model.RootInfo; +import com.android.internal.util.Preconditions; + +import java.util.Arrays; +import java.util.List; + +public class ManageRootActivity extends BaseActivity { + private static final int CODE_FORWARD = 42; + private static final String TAG = "ManageRootsActivity"; + + private Toolbar mToolbar; + private Spinner mToolbarStack; + + private DirectoryContainerView mDirectoryContainer; + + private ItemSelectedListener mStackListener; + private BaseAdapter mStackAdapter; + + public ManageRootActivity() { + super(R.layout.manage_roots_activity, TAG); + } + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + final Context context = this; + + mDrawer = DrawerController.createDummy(); + + mDirectoryContainer = (DirectoryContainerView) findViewById(R.id.container_directory); + + mToolbar = (Toolbar) findViewById(R.id.toolbar); + mToolbar.setTitleTextAppearance(context, + android.R.style.TextAppearance_DeviceDefault_Widget_ActionBar_Title); + + mStackAdapter = new StackAdapter(); + mStackListener = new ItemSelectedListener(); + mToolbarStack = (Spinner) findViewById(R.id.stack); + mToolbarStack.setOnItemSelectedListener(mStackListener); + + setActionBar(mToolbar); + + if (!mState.restored) { + // In this case, we set the activity title in AsyncTask.onPostExecute(). To prevent + // talkback from reading aloud the default title, we clear it here. + setTitle(""); + final Uri rootUri = getIntent().getData(); + new RestoreRootTask(rootUri).executeOnExecutor(getCurrentExecutor()); + } else { + onCurrentDirectoryChanged(ANIM_NONE); + } + } + + @Override + State buildState() { + State state = buildDefaultState(); + + state.action = ACTION_MANAGE; + state.acceptMimes = new String[] { "*/*" }; + state.allowMultiple = true; + state.showSize = true; + state.excludedAuthorities = getExcludedAuthorities(); + + return state; + } + + @Override + protected void onPostCreate(Bundle savedInstanceState) { + super.onPostCreate(savedInstanceState); + updateActionBar(); + } + + @Override + public void updateActionBar() { + // No navigation in manage root mode. + mToolbar.setNavigationIcon(null); + mToolbar.setNavigationOnClickListener(null); + + if (mSearchManager.isExpanded()) { + mToolbar.setTitle(null); + mToolbarStack.setVisibility(View.GONE); + mToolbarStack.setAdapter(null); + } else { + if (mState.stack.size() <= 1) { + mToolbar.setTitle(getCurrentRoot().title); + mToolbarStack.setVisibility(View.GONE); + mToolbarStack.setAdapter(null); + } else { + mToolbar.setTitle(null); + mToolbarStack.setVisibility(View.VISIBLE); + mToolbarStack.setAdapter(mStackAdapter); + + mStackListener.mIgnoreNextNavigation = true; + mToolbarStack.setSelection(mStackAdapter.getCount() - 1); + } + } + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + return true; + } + + @Override + void onDirectoryChanged(int anim) { + final FragmentManager fm = getFragmentManager(); + final RootInfo root = getCurrentRoot(); + final DocumentInfo cwd = getCurrentDirectory(); + + // If started in manage roots mode, there has to be a cwd (i.e. the root dir of the managed + // root). + Preconditions.checkNotNull(cwd); + mDirectoryContainer.setDrawDisappearingFirst(anim == ANIM_DOWN); + + if (mState.currentSearch != null) { + // Ongoing search + DirectoryFragment.showSearch(fm, root, mState.currentSearch, anim); + } else { + // Normal boring directory + DirectoryFragment.showNormal(fm, root, cwd, anim); + } + } + + @Override + public void onDocumentPicked(DocumentInfo doc, DocumentContext context) { + final FragmentManager fm = getFragmentManager(); + if (doc.isDirectory()) { + openDirectory(doc); + } else { + // First try managing the document; we expect manager to filter + // based on authority, so we don't grant. + final Intent manage = new Intent(DocumentsContract.ACTION_MANAGE_DOCUMENT); + manage.setData(doc.derivedUri); + + try { + startActivity(manage); + } catch (ActivityNotFoundException ex) { + // Fall back to viewing + final Intent view = new Intent(Intent.ACTION_VIEW); + view.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + view.setData(doc.derivedUri); + + try { + startActivity(view); + } catch (ActivityNotFoundException ex2) { + Toast.makeText(this, R.string.toast_no_application, Toast.LENGTH_SHORT).show(); + } + } + } + } + + @Override + public void onDocumentsPicked(List<DocumentInfo> docs) {} + + @Override + void saveStackBlocking() { + final ContentResolver resolver = getContentResolver(); + final ContentValues values = new ContentValues(); + + final byte[] rawStack = DurableUtils.writeToArrayOrNull(mState.stack); + + // Remember location for next app launch + final String packageName = getCallingPackageMaybeExtra(); + values.clear(); + values.put(ResumeColumns.STACK, rawStack); + values.put(ResumeColumns.EXTERNAL, 0); + resolver.insert(RecentsProvider.buildResume(packageName), values); + } + + @Override + void onTaskFinished(Uri... uris) { + Log.d(TAG, "onFinished() " + Arrays.toString(uris)); + + final Intent intent = new Intent(); + if (uris.length == 1) { + intent.setData(uris[0]); + } else if (uris.length > 1) { + final ClipData clipData = new ClipData( + null, mState.acceptMimes, new ClipData.Item(uris[0])); + for (int i = 1; i < uris.length; i++) { + clipData.addItem(new ClipData.Item(uris[i])); + } + intent.setClipData(clipData); + } + + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION + | Intent.FLAG_GRANT_WRITE_URI_PERMISSION + | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); + + setResult(Activity.RESULT_OK, intent); + finish(); + } + + public static ManageRootActivity get(Fragment fragment) { + return (ManageRootActivity) fragment.getActivity(); + } +} |