Merge "UX cleanups." into nyc-dev

This commit is contained in:
Steve McKay
2016-02-18 23:08:26 +00:00
committed by Android (Google) Code Review
13 changed files with 117 additions and 103 deletions

View File

@@ -61,7 +61,7 @@
android:layout_gravity="start"
android:orientation="vertical"
android:elevation="16dp"
android:background="@color/window_background">
android:background="@color/drawer_background">
<Toolbar
android:id="@+id/roots_toolbar"

View File

@@ -17,7 +17,7 @@
<com.android.documentsui.DirectoryView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/window_background"
android:background="@color/directory_background"
android:outlineProvider="bounds"
android:elevation="4dp"
android:orientation="vertical">
@@ -45,7 +45,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/window_background"
android:background="@color/directory_background"
android:focusable="true"
android:focusableInTouchMode="true"
android:visibility="gone">

View File

@@ -20,7 +20,7 @@
android:layout_height="wrap_content"
android:layout_margin="@dimen/grid_item_margin"
android:background="@color/item_doc_background"
android:elevation="5dp"
android:elevation="@dimen/grid_item_elevation"
android:focusable="true" >
<LinearLayout

View File

@@ -19,7 +19,7 @@
android:layout_height="wrap_content"
android:layout_margin="@dimen/grid_item_margin"
android:background="@color/item_doc_background"
android:elevation="5dp"
android:elevation="@dimen/grid_item_elevation"
android:focusable="true">
<!-- Main item thumbnail. Comprised of two overlapping images, the

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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.
-->
<resources>
<bool name="always_show_summary">true</bool>
</resources>

View File

@@ -15,8 +15,6 @@
-->
<resources>
<bool name="always_show_summary">true</bool>
<dimen name="list_item_height">64dp</dimen>
<dimen name="list_item_padding">24dp</dimen>

View File

@@ -21,6 +21,11 @@
else that needs to manually declare a background matching the "default"
app background (e.g. the drawer overlay). -->
<color name="window_background">#fff1f1f1</color>
<color name="drawer_background">#fff1f1f1</color>
<color name="directory_background">#fff7f7f7</color>
<color name="item_doc_background">#fffafafa</color>
<color name="item_doc_background_selected">#ffe0f2f1</color>
<color name="menu_search_background">#ff676f74</color>
<color name="primary_dark">@*android:color/primary_dark_material_dark</color>
<color name="primary">@*android:color/material_blue_grey_900</color>
@@ -29,10 +34,4 @@
<color name="band_select_background">#88ffffff</color>
<color name="band_select_border">#44000000</color>
<color name="item_doc_background">#fffafafa</color>
<color name="item_doc_background_selected">#ffe0f2f1</color>
<color name="menu_search_background">#ff676f74</color>
</resources>

View File

@@ -20,4 +20,6 @@
<!-- Intentionally unset. Vendors should set this in an overlay. -->
<string name="trusted_quick_viewer_package"></string>
<bool name="list_divider_inset_left">true</bool>
<bool name="always_show_summary">false</bool>
</resources>

View File

@@ -17,37 +17,24 @@
<resources>
<dimen name="grid_container_padding">10dp</dimen>
<dimen name="list_container_padding">0dp</dimen>
<dimen name="icon_size">40dp</dimen>
<dimen name="root_icon_size">24dp</dimen>
<dimen name="root_icon_margin">0dp</dimen>
<dimen name="check_icon_size">30dp</dimen>
<dimen name="list_item_thumbnail_size">40dp</dimen>
<dimen name="grid_item_icon_size">30dp</dimen>
<dimen name="progress_bar_height">4dp</dimen>
<dimen name="grid_width">152dp</dimen>
<dimen name="grid_height">176dp</dimen>
<dimen name="grid_item_width">152dp</dimen>
<dimen name="grid_item_height">176dp</dimen>
<dimen name="grid_item_margin">4dp</dimen>
<dimen name="grid_padding_horiz">4dp</dimen>
<dimen name="grid_padding_vert">4dp</dimen>
<dimen name="list_item_height">72dp</dimen>
<dimen name="list_item_padding">16dp</dimen>
<dimen name="list_divider_inset">72dp</dimen>
<bool name="list_divider_inset_left">true</bool>
<bool name="always_show_summary">false</bool>
<dimen name="dir_elevation">8dp</dimen>
<dimen name="drag_shadow_size">120dp</dimen>
<dimen name="grid_item_elevation">2dp</dimen>
</resources>

View File

@@ -31,12 +31,12 @@ import android.net.Uri;
import android.os.Bundle;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
import android.provider.DocumentsContract.Root;
import android.text.format.DateUtils;
import android.util.Log;
import com.android.documentsui.model.RootInfo;
import com.android.internal.annotations.GuardedBy;
import com.google.common.util.concurrent.AbstractFuture;
import libcore.io.IoUtils;
@@ -52,7 +52,7 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class RecentLoader extends AsyncTaskLoader<DirectoryResult> {
public class RecentsLoader extends AsyncTaskLoader<DirectoryResult> {
// TODO: clean up cursor ownership so background thread doesn't traverse
// previously returned cursors for filtering/sorting; this currently races
// with the UI thread.
@@ -80,7 +80,7 @@ public class RecentLoader extends AsyncTaskLoader<DirectoryResult> {
private final State mState;
@GuardedBy("mTasks")
private final HashMap<RootInfo, RecentTask> mTasks = new HashMap<>();
private final HashMap<RootInfo, RecentsTask> mTasks = new HashMap<>();
private final int mSortOrder = State.SORT_ORDER_LAST_MODIFIED;
@@ -89,69 +89,7 @@ public class RecentLoader extends AsyncTaskLoader<DirectoryResult> {
private DirectoryResult mResult;
// TODO: create better transfer of ownership around cursor to ensure its
// closed in all edge cases.
public class RecentTask extends AbstractFuture<Cursor> implements Runnable, Closeable {
public final String authority;
public final String rootId;
private Cursor mWithRoot;
public RecentTask(String authority, String rootId) {
this.authority = authority;
this.rootId = rootId;
}
@Override
public void run() {
if (isCancelled()) return;
try {
mQueryPermits.acquire();
} catch (InterruptedException e) {
return;
}
try {
runInternal();
} finally {
mQueryPermits.release();
}
}
public void runInternal() {
ContentProviderClient client = null;
try {
client = DocumentsApplication.acquireUnstableProviderOrThrow(
getContext().getContentResolver(), authority);
final Uri uri = DocumentsContract.buildRecentDocumentsUri(authority, rootId);
final Cursor cursor = client.query(
uri, null, null, null, DirectoryLoader.getQuerySortOrder(mSortOrder));
mWithRoot = new RootCursorWrapper(authority, rootId, cursor, MAX_DOCS_FROM_ROOT);
} catch (Exception e) {
Log.w(TAG, "Failed to load " + authority + ", " + rootId, e);
} finally {
ContentProviderClient.releaseQuietly(client);
}
set(mWithRoot);
mFirstPassLatch.countDown();
if (mFirstPassDone) {
onContentChanged();
}
}
@Override
public void close() throws IOException {
IoUtils.closeQuietly(mWithRoot);
}
}
public RecentLoader(Context context, RootsCache roots, State state) {
public RecentsLoader(Context context, RootsCache roots, State state) {
super(context);
mRoots = roots;
mState = state;
@@ -178,14 +116,13 @@ public class RecentLoader extends AsyncTaskLoader<DirectoryResult> {
final Collection<RootInfo> roots = mRoots.getMatchingRootsBlocking(mState);
for (RootInfo root : roots) {
if ((root.flags & Root.FLAG_SUPPORTS_RECENTS) != 0) {
final RecentTask task = new RecentTask(root.authority, root.rootId);
mTasks.put(root, task);
if (root.supportsRecents()) {
mTasks.put(root, new RecentsTask(root.authority, root.rootId));
}
}
mFirstPassLatch = new CountDownLatch(mTasks.size());
for (RecentTask task : mTasks.values()) {
for (RecentsTask task : mTasks.values()) {
ProviderExecutor.forAuthority(task.authority).execute(task);
}
@@ -202,7 +139,7 @@ public class RecentLoader extends AsyncTaskLoader<DirectoryResult> {
// Collect all finished tasks
boolean allDone = true;
List<Cursor> cursors = new ArrayList<>();
for (RecentTask task : mTasks.values()) {
for (RecentsTask task : mTasks.values()) {
if (task.isDone()) {
try {
final Cursor cursor = task.get();
@@ -303,7 +240,7 @@ public class RecentLoader extends AsyncTaskLoader<DirectoryResult> {
onStopLoading();
synchronized (mTasks) {
for (RecentTask task : mTasks.values()) {
for (RecentsTask task : mTasks.values()) {
IoUtils.closeQuietly(task);
}
}
@@ -311,4 +248,66 @@ public class RecentLoader extends AsyncTaskLoader<DirectoryResult> {
IoUtils.closeQuietly(mResult);
mResult = null;
}
// TODO: create better transfer of ownership around cursor to ensure its
// closed in all edge cases.
public class RecentsTask extends AbstractFuture<Cursor> implements Runnable, Closeable {
public final String authority;
public final String rootId;
private Cursor mWithRoot;
public RecentsTask(String authority, String rootId) {
this.authority = authority;
this.rootId = rootId;
}
@Override
public void run() {
if (isCancelled()) return;
try {
mQueryPermits.acquire();
} catch (InterruptedException e) {
return;
}
try {
runInternal();
} finally {
mQueryPermits.release();
}
}
public void runInternal() {
ContentProviderClient client = null;
try {
client = DocumentsApplication.acquireUnstableProviderOrThrow(
getContext().getContentResolver(), authority);
final Uri uri = DocumentsContract.buildRecentDocumentsUri(authority, rootId);
final Cursor cursor = client.query(
uri, null, null, null, DirectoryLoader.getQuerySortOrder(mSortOrder));
mWithRoot = new RootCursorWrapper(authority, rootId, cursor, MAX_DOCS_FROM_ROOT);
} catch (Exception e) {
Log.w(TAG, "Failed to load " + authority + ", " + rootId, e);
} finally {
ContentProviderClient.releaseQuietly(client);
}
set(mWithRoot);
mFirstPassLatch.countDown();
if (mFirstPassDone) {
onContentChanged();
}
}
@Override
public void close() throws IOException {
IoUtils.closeQuietly(mWithRoot);
}
}
}

View File

@@ -88,7 +88,7 @@ import com.android.documentsui.Menus;
import com.android.documentsui.MessageBar;
import com.android.documentsui.MimePredicate;
import com.android.documentsui.R;
import com.android.documentsui.RecentLoader;
import com.android.documentsui.RecentsLoader;
import com.android.documentsui.RootsCache;
import com.android.documentsui.Shared;
import com.android.documentsui.Snackbars;
@@ -320,7 +320,7 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi
context, mType, root, doc, contentsUri, state.userSortOrder);
case TYPE_RECENT_OPEN:
final RootsCache roots = DocumentsApplication.getRootsCache(context);
return new RecentLoader(context, roots, state);
return new RecentsLoader(context, roots, state);
default:
throw new IllegalStateException("Unknown type " + mType);
}

View File

@@ -241,8 +241,10 @@ public class RootInfo implements Durable, Parcelable {
}
public boolean isLibrary() {
return derivedType == TYPE_IMAGES || derivedType == TYPE_VIDEO || derivedType == TYPE_AUDIO
|| derivedType == TYPE_RECENTS || derivedType == TYPE_DOWNLOADS;
return derivedType == TYPE_IMAGES
|| derivedType == TYPE_VIDEO
|| derivedType == TYPE_AUDIO
|| derivedType == TYPE_RECENTS;
}
public boolean hasSettings() {
@@ -257,6 +259,14 @@ public class RootInfo implements Durable, Parcelable {
return (flags & Root.FLAG_SUPPORTS_CREATE) != 0;
}
public boolean supportsRecents() {
return (flags & Root.FLAG_SUPPORTS_RECENTS) != 0;
}
public boolean supportsSearch() {
return (flags & Root.FLAG_SUPPORTS_SEARCH) != 0;
}
public boolean isAdvanced() {
return (flags & Root.FLAG_ADVANCED) != 0;
}