summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--res/drawable/launcher_screen.xml2
-rw-r--r--res/drawable/launcher_screen_night.xml2
-rw-r--r--res/drawable/list_divider.xml2
-rw-r--r--res/drawable/splash_screen.xml64
-rw-r--r--res/layout/dialog_file_name.xml1
-rw-r--r--res/values-night/colors.xml2
-rw-r--r--res/values/colors.xml2
-rw-r--r--src/com/android/documentsui/DirectoryLoader.java12
-rw-r--r--src/com/android/documentsui/MultiRootDocumentsLoader.java13
-rw-r--r--src/com/android/documentsui/base/FilteringCursorWrapper.java111
10 files changed, 148 insertions, 63 deletions
diff --git a/res/drawable/launcher_screen.xml b/res/drawable/launcher_screen.xml
index 485160615..c0d814632 100644
--- a/res/drawable/launcher_screen.xml
+++ b/res/drawable/launcher_screen.xml
@@ -3,7 +3,7 @@
<item android:drawable="@android:color/white"/>
<item
- android:drawable="@drawable/app_icon"
+ android:drawable="@drawable/splash_screen"
android:height="150dp"
android:width="150dp"
android:gravity="center"/>
diff --git a/res/drawable/launcher_screen_night.xml b/res/drawable/launcher_screen_night.xml
index 8a9ffd3a6..983c4977d 100644
--- a/res/drawable/launcher_screen_night.xml
+++ b/res/drawable/launcher_screen_night.xml
@@ -3,7 +3,7 @@
<item android:drawable="@color/app_background_color"/>
<item
- android:drawable="@drawable/app_icon"
+ android:drawable="@drawable/splash_screen"
android:height="150dp"
android:width="150dp"
android:gravity="center"/>
diff --git a/res/drawable/list_divider.xml b/res/drawable/list_divider.xml
index 5768aff8a..5067af08e 100644
--- a/res/drawable/list_divider.xml
+++ b/res/drawable/list_divider.xml
@@ -16,7 +16,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:tint="?android:attr/colorForeground">
- <solid android:color="#1f000000" />
+ <solid android:color="@color/list_divider_color" />
<size
android:height="1dp"
android:width="1dp" />
diff --git a/res/drawable/splash_screen.xml b/res/drawable/splash_screen.xml
new file mode 100644
index 000000000..3f0c48b6b
--- /dev/null
+++ b/res/drawable/splash_screen.xml
@@ -0,0 +1,64 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:pathData="M12,12m-11,0a11,11 0,1 1,22 0a11,11 0,1 1,-22 0"
+ android:fillColor="#4285F4"/>
+ <path
+ android:pathData="M23,12c0,6.1 -4.9,11 -11,11S1,18.1 1,12c0,0 0,0 0,-0.1c0,6 4.9,10.9 11,10.9S23,18 23,12C23,12 23,12 23,12z"
+ android:strokeAlpha="0.2"
+ android:fillColor="#263238"
+ android:fillAlpha="0.2"/>
+ <path
+ android:pathData="M23,12C23,12 23,12 23,12c0,-6 -4.9,-10.9 -11,-10.9S1,6 1,12.1c0,0 0,0 0,-0.1C1,5.9 5.9,1 12,1S23,5.9 23,12z"
+ android:strokeAlpha="0.2"
+ android:fillColor="#FFFFFF"
+ android:fillAlpha="0.2"/>
+ <path
+ android:pathData="M22.8,14.2c-1,4.8 -5,8.4 -9.9,8.8l-6.4,-6.4L17.6,9C17.6,9 22.8,14.2 22.8,14.2z"
+ android:fillColor="#4285F4"/>
+ <path
+ android:pathData="M22.8,14.2c-1,4.8 -5,8.4 -9.9,8.8l-6.4,-6.4L17.6,9C17.6,9 22.8,14.2 22.8,14.2z">
+ <aapt:attr name="android:fillColor">
+ <gradient
+ android:startY="12.203438"
+ android:startX="11.452812"
+ android:endY="20.219812"
+ android:endX="19.469187"
+ android:type="linear">
+ <item android:offset="0" android:color="#33263238"/>
+ <item android:offset="1" android:color="#05263238"/>
+ </gradient>
+ </aapt:attr>
+ </path>
+ <path
+ android:pathData="M16.5,8.5H12L10.8,7H7.5C6.7,7 6,7.7 6,8.5v7C6,16.3 6.7,17 7.5,17h9c0.8,0 1.5,-0.7 1.5,-1.5V10C18,9.2 17.3,8.5 16.5,8.5z"
+ android:fillColor="#F5F5F5"/>
+ <path
+ android:pathData="M18,10v0.1c0,-0.8 -0.7,-1.5 -1.5,-1.5H12l-1.2,-1.5H7.5C6.7,7.1 6,7.8 6,8.6V8.5C6,7.7 6.7,7 7.5,7h3.2L12,8.5h4.5C17.3,8.5 18,9.2 18,10z"
+ android:strokeAlpha="0.4"
+ android:fillColor="#FFFFFF"
+ android:fillAlpha="0.4"/>
+ <path
+ android:pathData="M18,15.5v0.1c0,0.8 -0.7,1.5 -1.5,1.5h-9c-0.8,0 -1.5,-0.7 -1.5,-1.5v-0.1C6,16.3 6.7,17 7.5,17h9C17.3,17 18,16.3 18,15.5z"
+ android:strokeAlpha="0.2"
+ android:fillColor="#263238"
+ android:fillAlpha="0.2"/>
+ <path
+ android:pathData="M12,12m-11,0a11,11 0,1 1,22 0a11,11 0,1 1,-22 0"
+ android:fillAlpha="0.1">
+ <aapt:attr name="android:fillColor">
+ <gradient
+ android:gradientRadius="22.333876"
+ android:centerX="3.238875"
+ android:centerY="5.0445"
+ android:type="radial">
+ <item android:offset="0" android:color="#FFFFFFFF"/>
+ <item android:offset="1" android:color="#00FFFFFF"/>
+ </gradient>
+ </aapt:attr>
+ </path>
+</vector>
diff --git a/res/layout/dialog_file_name.xml b/res/layout/dialog_file_name.xml
index 0ebd936d0..7f2a9592b 100644
--- a/res/layout/dialog_file_name.xml
+++ b/res/layout/dialog_file_name.xml
@@ -35,6 +35,7 @@
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:maxLength="255"
android:inputType="textCapSentences"/>
</com.google.android.material.textfield.TextInputLayout>
diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml
index 86bcbbc48..1da85cde8 100644
--- a/res/values-night/colors.xml
+++ b/res/values-night/colors.xml
@@ -33,4 +33,6 @@
<!-- AppCompat.textColorSecondary -->
<color name="doc_list_item_subtitle_enabled">#b3ffffff</color>
<color name="doc_list_item_subtitle_disabled">#36ffffff</color>
+
+ <color name="list_divider_color">#9aa0a6</color>
</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index e00984ada..aa0c3a4ce 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -52,4 +52,6 @@
<color name="doc_list_item_subtitle_enabled">#5F6368</color> <!-- Gray 700 -->
<color name="doc_list_item_subtitle_disabled">#613c4043</color> <!-- 38% Grey800 -->
+
+ <color name="list_divider_color">#1f000000</color>
</resources>
diff --git a/src/com/android/documentsui/DirectoryLoader.java b/src/com/android/documentsui/DirectoryLoader.java
index d90d51f74..2775ec4bb 100644
--- a/src/com/android/documentsui/DirectoryLoader.java
+++ b/src/com/android/documentsui/DirectoryLoader.java
@@ -56,7 +56,6 @@ import java.util.concurrent.Executor;
public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> {
private static final String TAG = "DirectoryLoader";
-
private static final String[] SEARCH_REJECT_MIMES = new String[] { Document.MIME_TYPE_DIR };
private static final String[] PHOTO_PICKING_ACCEPT_MIMES = new String[]
{Document.MIME_TYPE_DIR, MimeTypes.IMAGE_MIME};
@@ -178,17 +177,16 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> {
}
cursor.registerContentObserver(mObserver);
- // Filter hidden files.
- cursor = new FilteringCursorWrapper(cursor, mState.showHiddenFiles);
-
+ FilteringCursorWrapper filteringCursor = new FilteringCursorWrapper(cursor);
+ filteringCursor.filterHiddenFiles(mState.showHiddenFiles);
if (mSearchMode && !mFeatures.isFoldersInSearchResultsEnabled()) {
// There is no findDocumentPath API. Enable filtering on folders in search mode.
- cursor = new FilteringCursorWrapper(cursor, null, SEARCH_REJECT_MIMES);
+ filteringCursor.filterMimes(/* acceptMimes= */ null, SEARCH_REJECT_MIMES);
}
-
if (mPhotoPicking) {
- cursor = new FilteringCursorWrapper(cursor, PHOTO_PICKING_ACCEPT_MIMES, null);
+ filteringCursor.filterMimes(PHOTO_PICKING_ACCEPT_MIMES, /* rejectMimes= */ null);
}
+ cursor = filteringCursor;
// TODO: When API tweaks have landed, use ContentResolver.EXTRA_HONORED_ARGS
// instead of checking directly for ContentResolver.QUERY_ARG_SORT_COLUMNS (won't work)
diff --git a/src/com/android/documentsui/MultiRootDocumentsLoader.java b/src/com/android/documentsui/MultiRootDocumentsLoader.java
index 065c99aaa..b25828dda 100644
--- a/src/com/android/documentsui/MultiRootDocumentsLoader.java
+++ b/src/com/android/documentsui/MultiRootDocumentsLoader.java
@@ -179,17 +179,18 @@ public abstract class MultiRootDocumentsLoader extends AsyncTaskLoader<Directory
continue;
}
- // Filter hidden files.
- cursor = new FilteringCursorWrapper(cursor, mState.showHiddenFiles);
-
- final FilteringCursorWrapper filtered = new FilteringCursorWrapper(
- cursor, mState.acceptMimes, getRejectMimes(), rejectBefore) {
+ final FilteringCursorWrapper filteredCursor =
+ new FilteringCursorWrapper(cursor) {
@Override
public void close() {
// Ignored, since we manage cursor lifecycle internally
}
};
- cursors.add(filtered);
+ filteredCursor.filterHiddenFiles(mState.showHiddenFiles);
+ filteredCursor.filterMimes(mState.acceptMimes, getRejectMimes());
+ filteredCursor.filterLastModified(rejectBefore);
+
+ cursors.add(filteredCursor);
}
} catch (InterruptedException e) {
diff --git a/src/com/android/documentsui/base/FilteringCursorWrapper.java b/src/com/android/documentsui/base/FilteringCursorWrapper.java
index 67b7533e5..577e47c33 100644
--- a/src/com/android/documentsui/base/FilteringCursorWrapper.java
+++ b/src/com/android/documentsui/base/FilteringCursorWrapper.java
@@ -29,68 +29,62 @@ import android.provider.DocumentsContract.Document;
import android.util.Log;
/**
- * Cursor wrapper that filters MIME types not matching given list.
+ * Cursor wrapper that filters cursor results by given conditions.
*/
public class FilteringCursorWrapper extends AbstractCursor {
private final Cursor mCursor;
- private final int[] mPosition;
+ private int[] mPositions;
private int mCount;
- public FilteringCursorWrapper(Cursor cursor, String[] acceptMimes) {
- this(cursor, acceptMimes, null, Long.MIN_VALUE);
- }
-
- public FilteringCursorWrapper(Cursor cursor, String[] acceptMimes, String[] rejectMimes) {
- this(cursor, acceptMimes, rejectMimes, Long.MIN_VALUE);
- }
-
- public FilteringCursorWrapper(
- Cursor cursor, String[] acceptMimes, String[] rejectMimes, long rejectBefore) {
+ public FilteringCursorWrapper(Cursor cursor) {
mCursor = cursor;
+ mCount = cursor.getCount();
+ mPositions = new int[mCount];
+ for (int i = 0; i < mCount; i++) {
+ mPositions[i] = i;
+ }
+ }
- final int count = cursor.getCount();
- mPosition = new int[count];
-
- cursor.moveToPosition(-1);
- while (cursor.moveToNext() && mCount < count) {
+ /**
+ * Filters cursor according to mimes. If both lists are empty, all mimes will be rejected.
+ *
+ * @param acceptMimes allowed list of mimes
+ * @param rejectMimes blocked list of mimes
+ */
+ public void filterMimes(String[] acceptMimes, String[] rejectMimes) {
+ filterByCondition((cursor) -> {
final String mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
- final long lastModified = getCursorLong(cursor, Document.COLUMN_LAST_MODIFIED);
if (rejectMimes != null && MimeTypes.mimeMatches(rejectMimes, mimeType)) {
- continue;
+ return false;
}
- if (lastModified < rejectBefore) {
- continue;
- }
- if (MimeTypes.mimeMatches(acceptMimes, mimeType)) {
- mPosition[mCount++] = cursor.getPosition();
- }
- }
-
- if (DEBUG && mCount != cursor.getCount()) {
- Log.d(TAG, "Before filtering " + cursor.getCount() + ", after " + mCount);
- }
+ return MimeTypes.mimeMatches(acceptMimes, mimeType);
+ });
}
- public FilteringCursorWrapper(Cursor cursor, boolean showHiddenFiles) {
- mCursor = cursor;
-
- final int count = cursor.getCount();
- mPosition = new int[count];
+ /** Filters cursor according to last modified time, and reject earlier than given timestamp. */
+ public void filterLastModified(long rejectBeforeTimestamp) {
+ filterByCondition((cursor) -> {
+ final long lastModified = getCursorLong(cursor, Document.COLUMN_LAST_MODIFIED);
+ return lastModified >= rejectBeforeTimestamp;
+ });
+ }
- cursor.moveToPosition(-1);
- while (cursor.moveToNext() && mCount < count) {
- final String documentId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
- if (!showHiddenFiles && documentId != null
- && (documentId.startsWith(".") || documentId.contains("/."))) {
- continue;
- }
- mPosition[mCount++] = cursor.getPosition();
+ /** Filter hidden files based on preference. */
+ public void filterHiddenFiles(boolean showHiddenFiles) {
+ if (showHiddenFiles) {
+ return;
}
- if (DEBUG && mCount != cursor.getCount()) {
- Log.d(TAG, "Before filtering " + cursor.getCount() + ", after " + mCount);
- }
+ filterByCondition((cursor) -> {
+ // Judge by name and documentId separately because for some providers
+ // e.g. DownloadProvider, documentId may not contain file name.
+ final String name = getCursorString(cursor, Document.COLUMN_DISPLAY_NAME);
+ final String documentId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
+ boolean documentIdHidden = documentId != null && documentId.contains("/.");
+ boolean fileNameHidden = name != null && name.startsWith(".");
+ return !(documentIdHidden || fileNameHidden);
+ });
}
@Override
@@ -106,7 +100,7 @@ public class FilteringCursorWrapper extends AbstractCursor {
@Override
public boolean onMove(int oldPosition, int newPosition) {
- return mCursor.moveToPosition(mPosition[newPosition]);
+ return mCursor.moveToPosition(mPositions[newPosition]);
}
@Override
@@ -168,4 +162,27 @@ public class FilteringCursorWrapper extends AbstractCursor {
public void unregisterContentObserver(ContentObserver observer) {
mCursor.unregisterContentObserver(observer);
}
+
+ private interface FilteringCondition {
+ boolean accept(Cursor cursor);
+ }
+
+ private void filterByCondition(FilteringCondition condition) {
+ final int oldCount = this.getCount();
+ int[] newPositions = new int[oldCount];
+ int newCount = 0;
+
+ this.moveToPosition(-1);
+ while (this.moveToNext() && newCount < oldCount) {
+ if (condition.accept(mCursor)) {
+ newPositions[newCount++] = mPositions[this.getPosition()];
+ }
+ }
+
+ if (DEBUG && newCount != this.getCount()) {
+ Log.d(TAG, "Before filtering " + oldCount + ", after " + newCount);
+ }
+ mCount = newCount;
+ mPositions = newPositions;
+ }
}