Loading res/drawable/ic_chip_large_files.xml 0 → 100644 +25 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2019 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. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> <path android:fillColor="?android:textColorSecondary" android:pathData="M21.41,11.58l-9,-9C12.05,2.22 11.55,2 11,2H4c-1.1,0 -2,0.9 -2,2v7c0,0.55 0.22,1.05 0.59,1.42l9,9c0.36,0.36 0.86,0.58 1.41,0.58s1.05,-0.22 1.41,-0.59l7,-7c0.37,-0.36 0.59,-0.86 0.59,-1.41s-0.23,-1.06 -0.59,-1.42zM13,20.01L4,11V4h7v-0.01l9,9 -7,7.02zM8,6.5C8,7.33 7.33,8 6.5,8S5,7.33 5,6.5 5.67,5 6.5,5 8,5.67 8,6.5z"/> </vector> No newline at end of file res/values/strings.xml +4 −0 Original line number Diff line number Diff line Loading @@ -433,6 +433,10 @@ <string name="chip_title_videos">Videos</string> <!-- Title for image chip. [CHAR_LIMIT=25] --> <string name="chip_title_documents">Documents</string> <!-- Title for large file chip. [CHAR_LIMIT=25] --> <string name="chip_title_large_files">Large files</string> <!-- Title for from this week chip. [CHAR_LIMIT=25] --> <string name="chip_title_from_this_week">From this week</string> <!-- Hint on text input field for create new folder. [CHAR_LIMIT=48] --> <string name="input_hint_new_folder">Folder name</string> Loading src/com/android/documentsui/MetricConsts.java +5 −1 Original line number Diff line number Diff line Loading @@ -363,6 +363,8 @@ public class MetricConsts { public static final int TYPE_CHIP_DOCS = 4; public static final int TYPE_SEARCH_HISTORY = 5; public static final int TYPE_SEARCH_STRING = 6; public static final int TYPE_CHIP_LARGE_FILES = 7; public static final int TYPE_CHIP_FROM_THIS_WEEK = 8; @IntDef(flag = true, value = { TYPE_UNKNOWN, Loading @@ -371,7 +373,9 @@ public class MetricConsts { TYPE_CHIP_VIDEOS, TYPE_CHIP_DOCS, TYPE_SEARCH_HISTORY, TYPE_SEARCH_STRING TYPE_SEARCH_STRING, TYPE_CHIP_LARGE_FILES, TYPE_CHIP_FROM_THIS_WEEK }) @Retention(RetentionPolicy.SOURCE) public @interface SearchType {} Loading src/com/android/documentsui/queries/SearchChipViewManager.java +61 −18 Original line number Diff line number Diff line Loading @@ -18,7 +18,9 @@ package com.android.documentsui.queries; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.provider.DocumentsContract; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; Loading @@ -37,6 +39,8 @@ import com.android.documentsui.base.Shared; import com.google.android.material.chip.Chip; import com.google.common.primitives.Ints; import java.time.LocalDate; import java.time.ZoneId; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; Loading @@ -51,13 +55,21 @@ import java.util.Set; * Manages search chip behavior. */ public class SearchChipViewManager { private static final int CHIP_MOVE_ANIMATION_DURATION = 250; private static final int TYPE_IMAGES = MetricConsts.TYPE_CHIP_IMAGES;; // Defined large file as the size is larger than 10 MB. private static final long LARGE_FILE_SIZE_BYTES = 10000000L; // Defined a week ago as now in millis. private static final long A_WEEK_AGO_MILLIS = LocalDate.now().minusDays(7).atStartOfDay(ZoneId.systemDefault()) .toInstant() .toEpochMilli(); private static final int TYPE_IMAGES = MetricConsts.TYPE_CHIP_IMAGES; private static final int TYPE_DOCUMENTS = MetricConsts.TYPE_CHIP_DOCS; private static final int TYPE_AUDIO = MetricConsts.TYPE_CHIP_AUDIOS; private static final int TYPE_VIDEOS = MetricConsts.TYPE_CHIP_VIDEOS; private static final int TYPE_LARGE_FILES = MetricConsts.TYPE_CHIP_LARGE_FILES; private static final int TYPE_FROM_THIS_WEEK = MetricConsts.TYPE_CHIP_FROM_THIS_WEEK; private static final ChipComparator CHIP_COMPARATOR = new ChipComparator(); Loading @@ -67,6 +79,7 @@ public class SearchChipViewManager { private static final String[] AUDIO_MIMETYPES = new String[]{"audio/*", "application/ogg", "application/x-flac"}; private static final String[] DOCUMENTS_MIMETYPES = new String[]{"application/*", "text/*"}; private static final String[] EMPTY_MIMETYPES = new String[]{""}; private static final Map<Integer, SearchChipData> sChipItems = new HashMap<>(); Loading @@ -89,6 +102,14 @@ public class SearchChipViewManager { new SearchChipData(TYPE_AUDIO, R.string.chip_title_audio, AUDIO_MIMETYPES)); sChipItems.put(TYPE_VIDEOS, new SearchChipData(TYPE_VIDEOS, R.string.chip_title_videos, VIDEOS_MIMETYPES)); sChipItems.put(TYPE_LARGE_FILES, new SearchChipData(TYPE_LARGE_FILES, R.string.chip_title_large_files, EMPTY_MIMETYPES)); sChipItems.put(TYPE_FROM_THIS_WEEK, new SearchChipData(TYPE_FROM_THIS_WEEK, R.string.chip_title_from_this_week, EMPTY_MIMETYPES)); } public SearchChipViewManager(@NonNull ViewGroup chipGroup) { Loading Loading @@ -145,18 +166,33 @@ public class SearchChipViewManager { } /** * Get the mime types of checked chips * Get the query arguments of the checked chips. * * @return the string array of mime types * @return the bundle of query arguments */ public String[] getCheckedMimeTypes() { final ArrayList<String> args = new ArrayList<>(); public Bundle getCheckedChipQueryArgs() { final Bundle queryArgs = new Bundle(); final ArrayList<String> checkedMimeTypes = new ArrayList<>(); for (SearchChipData data : mCheckedChipItems) { if (data.getChipType() == MetricConsts.TYPE_CHIP_LARGE_FILES) { queryArgs.putLong(DocumentsContract.QUERY_ARG_FILE_SIZE_OVER, LARGE_FILE_SIZE_BYTES); } else if (data.getChipType() == MetricConsts.TYPE_CHIP_FROM_THIS_WEEK) { queryArgs.putLong(DocumentsContract.QUERY_ARG_LAST_MODIFIED_AFTER, A_WEEK_AGO_MILLIS); } else { for (String mimeType : data.getMimeTypes()) { args.add(mimeType); checkedMimeTypes.add(mimeType); } } return args.toArray(new String[0]); } if (!checkedMimeTypes.isEmpty()) { queryArgs.putStringArray(DocumentsContract.QUERY_ARG_MIME_TYPES, checkedMimeTypes.toArray(new String[0])); } return queryArgs; } /** Loading Loading @@ -209,7 +245,9 @@ public class SearchChipViewManager { for (Integer chipType : mDefaultChipTypes) { final SearchChipData chipData = sChipItems.get(chipType); final String[] mimeTypes = chipData.getMimeTypes(); final boolean isMatched = MimeTypes.mimeMatches(acceptMimeTypes, mimeTypes); final boolean isMatched = (chipType == MetricConsts.TYPE_CHIP_LARGE_FILES || chipType == MetricConsts.TYPE_CHIP_FROM_THIS_WEEK) || MimeTypes.mimeMatches(acceptMimeTypes, mimeTypes); if (isMatched) { addChipToGroup(mChipGroup, chipData, inflater); } Loading @@ -217,9 +255,6 @@ public class SearchChipViewManager { reorderCheckedChips(null /* clickedChip */, false /* hasAnim */); mIsFirstUpdateChipsReady = true; mCurrentUpdateMimeTypes = acceptMimeTypes; if (mChipGroup.getChildCount() < 2) { mChipGroup.setVisibility(View.GONE); } } private void addChipToGroup(ViewGroup group, SearchChipData data, LayoutInflater inflater) { Loading Loading @@ -317,11 +352,19 @@ public class SearchChipViewManager { } private void bindChip(Chip chip, SearchChipData chipData) { final Context context = mChipGroup.getContext(); chip.setTag(chipData); chip.setText(mChipGroup.getContext().getString(chipData.getTitleRes())); // get the icon drawable with the first mimeType chip.setChipIcon( IconUtils.loadMimeIcon(mChipGroup.getContext(), chipData.getMimeTypes()[0])); chip.setText(context.getString(chipData.getTitleRes())); Drawable chipIcon; if (chipData.getChipType() == TYPE_LARGE_FILES) { chipIcon = context.getDrawable(R.drawable.ic_chip_large_files); } else if (chipData.getChipType() == TYPE_FROM_THIS_WEEK) { chipIcon = context.getDrawable(R.drawable.ic_history); } else { // get the icon drawable with the first mimeType in chipData chipIcon = IconUtils.loadMimeIcon(context, chipData.getMimeTypes()[0]); } chip.setChipIcon(chipIcon); chip.setOnClickListener(this::onChipClick); if (mCheckedChipItems.contains(chipData)) { Loading src/com/android/documentsui/queries/SearchViewManager.java +1 −5 Original line number Diff line number Diff line Loading @@ -162,15 +162,11 @@ public class SearchViewManager implements * @return the bundle of query arguments */ public Bundle buildQueryArgs() { final Bundle queryArgs = new Bundle(); final Bundle queryArgs = mChipViewManager.getCheckedChipQueryArgs(); if (!TextUtils.isEmpty(mCurrentSearch)) { queryArgs.putString(DocumentsContract.QUERY_ARG_DISPLAY_NAME, mCurrentSearch); } final String[] checkedMimeTypes = mChipViewManager.getCheckedMimeTypes(); if (checkedMimeTypes != null && checkedMimeTypes.length > 0) { queryArgs.putStringArray(DocumentsContract.QUERY_ARG_MIME_TYPES, checkedMimeTypes); } return queryArgs; } Loading Loading
res/drawable/ic_chip_large_files.xml 0 → 100644 +25 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2019 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. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> <path android:fillColor="?android:textColorSecondary" android:pathData="M21.41,11.58l-9,-9C12.05,2.22 11.55,2 11,2H4c-1.1,0 -2,0.9 -2,2v7c0,0.55 0.22,1.05 0.59,1.42l9,9c0.36,0.36 0.86,0.58 1.41,0.58s1.05,-0.22 1.41,-0.59l7,-7c0.37,-0.36 0.59,-0.86 0.59,-1.41s-0.23,-1.06 -0.59,-1.42zM13,20.01L4,11V4h7v-0.01l9,9 -7,7.02zM8,6.5C8,7.33 7.33,8 6.5,8S5,7.33 5,6.5 5.67,5 6.5,5 8,5.67 8,6.5z"/> </vector> No newline at end of file
res/values/strings.xml +4 −0 Original line number Diff line number Diff line Loading @@ -433,6 +433,10 @@ <string name="chip_title_videos">Videos</string> <!-- Title for image chip. [CHAR_LIMIT=25] --> <string name="chip_title_documents">Documents</string> <!-- Title for large file chip. [CHAR_LIMIT=25] --> <string name="chip_title_large_files">Large files</string> <!-- Title for from this week chip. [CHAR_LIMIT=25] --> <string name="chip_title_from_this_week">From this week</string> <!-- Hint on text input field for create new folder. [CHAR_LIMIT=48] --> <string name="input_hint_new_folder">Folder name</string> Loading
src/com/android/documentsui/MetricConsts.java +5 −1 Original line number Diff line number Diff line Loading @@ -363,6 +363,8 @@ public class MetricConsts { public static final int TYPE_CHIP_DOCS = 4; public static final int TYPE_SEARCH_HISTORY = 5; public static final int TYPE_SEARCH_STRING = 6; public static final int TYPE_CHIP_LARGE_FILES = 7; public static final int TYPE_CHIP_FROM_THIS_WEEK = 8; @IntDef(flag = true, value = { TYPE_UNKNOWN, Loading @@ -371,7 +373,9 @@ public class MetricConsts { TYPE_CHIP_VIDEOS, TYPE_CHIP_DOCS, TYPE_SEARCH_HISTORY, TYPE_SEARCH_STRING TYPE_SEARCH_STRING, TYPE_CHIP_LARGE_FILES, TYPE_CHIP_FROM_THIS_WEEK }) @Retention(RetentionPolicy.SOURCE) public @interface SearchType {} Loading
src/com/android/documentsui/queries/SearchChipViewManager.java +61 −18 Original line number Diff line number Diff line Loading @@ -18,7 +18,9 @@ package com.android.documentsui.queries; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.provider.DocumentsContract; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; Loading @@ -37,6 +39,8 @@ import com.android.documentsui.base.Shared; import com.google.android.material.chip.Chip; import com.google.common.primitives.Ints; import java.time.LocalDate; import java.time.ZoneId; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; Loading @@ -51,13 +55,21 @@ import java.util.Set; * Manages search chip behavior. */ public class SearchChipViewManager { private static final int CHIP_MOVE_ANIMATION_DURATION = 250; private static final int TYPE_IMAGES = MetricConsts.TYPE_CHIP_IMAGES;; // Defined large file as the size is larger than 10 MB. private static final long LARGE_FILE_SIZE_BYTES = 10000000L; // Defined a week ago as now in millis. private static final long A_WEEK_AGO_MILLIS = LocalDate.now().minusDays(7).atStartOfDay(ZoneId.systemDefault()) .toInstant() .toEpochMilli(); private static final int TYPE_IMAGES = MetricConsts.TYPE_CHIP_IMAGES; private static final int TYPE_DOCUMENTS = MetricConsts.TYPE_CHIP_DOCS; private static final int TYPE_AUDIO = MetricConsts.TYPE_CHIP_AUDIOS; private static final int TYPE_VIDEOS = MetricConsts.TYPE_CHIP_VIDEOS; private static final int TYPE_LARGE_FILES = MetricConsts.TYPE_CHIP_LARGE_FILES; private static final int TYPE_FROM_THIS_WEEK = MetricConsts.TYPE_CHIP_FROM_THIS_WEEK; private static final ChipComparator CHIP_COMPARATOR = new ChipComparator(); Loading @@ -67,6 +79,7 @@ public class SearchChipViewManager { private static final String[] AUDIO_MIMETYPES = new String[]{"audio/*", "application/ogg", "application/x-flac"}; private static final String[] DOCUMENTS_MIMETYPES = new String[]{"application/*", "text/*"}; private static final String[] EMPTY_MIMETYPES = new String[]{""}; private static final Map<Integer, SearchChipData> sChipItems = new HashMap<>(); Loading @@ -89,6 +102,14 @@ public class SearchChipViewManager { new SearchChipData(TYPE_AUDIO, R.string.chip_title_audio, AUDIO_MIMETYPES)); sChipItems.put(TYPE_VIDEOS, new SearchChipData(TYPE_VIDEOS, R.string.chip_title_videos, VIDEOS_MIMETYPES)); sChipItems.put(TYPE_LARGE_FILES, new SearchChipData(TYPE_LARGE_FILES, R.string.chip_title_large_files, EMPTY_MIMETYPES)); sChipItems.put(TYPE_FROM_THIS_WEEK, new SearchChipData(TYPE_FROM_THIS_WEEK, R.string.chip_title_from_this_week, EMPTY_MIMETYPES)); } public SearchChipViewManager(@NonNull ViewGroup chipGroup) { Loading Loading @@ -145,18 +166,33 @@ public class SearchChipViewManager { } /** * Get the mime types of checked chips * Get the query arguments of the checked chips. * * @return the string array of mime types * @return the bundle of query arguments */ public String[] getCheckedMimeTypes() { final ArrayList<String> args = new ArrayList<>(); public Bundle getCheckedChipQueryArgs() { final Bundle queryArgs = new Bundle(); final ArrayList<String> checkedMimeTypes = new ArrayList<>(); for (SearchChipData data : mCheckedChipItems) { if (data.getChipType() == MetricConsts.TYPE_CHIP_LARGE_FILES) { queryArgs.putLong(DocumentsContract.QUERY_ARG_FILE_SIZE_OVER, LARGE_FILE_SIZE_BYTES); } else if (data.getChipType() == MetricConsts.TYPE_CHIP_FROM_THIS_WEEK) { queryArgs.putLong(DocumentsContract.QUERY_ARG_LAST_MODIFIED_AFTER, A_WEEK_AGO_MILLIS); } else { for (String mimeType : data.getMimeTypes()) { args.add(mimeType); checkedMimeTypes.add(mimeType); } } return args.toArray(new String[0]); } if (!checkedMimeTypes.isEmpty()) { queryArgs.putStringArray(DocumentsContract.QUERY_ARG_MIME_TYPES, checkedMimeTypes.toArray(new String[0])); } return queryArgs; } /** Loading Loading @@ -209,7 +245,9 @@ public class SearchChipViewManager { for (Integer chipType : mDefaultChipTypes) { final SearchChipData chipData = sChipItems.get(chipType); final String[] mimeTypes = chipData.getMimeTypes(); final boolean isMatched = MimeTypes.mimeMatches(acceptMimeTypes, mimeTypes); final boolean isMatched = (chipType == MetricConsts.TYPE_CHIP_LARGE_FILES || chipType == MetricConsts.TYPE_CHIP_FROM_THIS_WEEK) || MimeTypes.mimeMatches(acceptMimeTypes, mimeTypes); if (isMatched) { addChipToGroup(mChipGroup, chipData, inflater); } Loading @@ -217,9 +255,6 @@ public class SearchChipViewManager { reorderCheckedChips(null /* clickedChip */, false /* hasAnim */); mIsFirstUpdateChipsReady = true; mCurrentUpdateMimeTypes = acceptMimeTypes; if (mChipGroup.getChildCount() < 2) { mChipGroup.setVisibility(View.GONE); } } private void addChipToGroup(ViewGroup group, SearchChipData data, LayoutInflater inflater) { Loading Loading @@ -317,11 +352,19 @@ public class SearchChipViewManager { } private void bindChip(Chip chip, SearchChipData chipData) { final Context context = mChipGroup.getContext(); chip.setTag(chipData); chip.setText(mChipGroup.getContext().getString(chipData.getTitleRes())); // get the icon drawable with the first mimeType chip.setChipIcon( IconUtils.loadMimeIcon(mChipGroup.getContext(), chipData.getMimeTypes()[0])); chip.setText(context.getString(chipData.getTitleRes())); Drawable chipIcon; if (chipData.getChipType() == TYPE_LARGE_FILES) { chipIcon = context.getDrawable(R.drawable.ic_chip_large_files); } else if (chipData.getChipType() == TYPE_FROM_THIS_WEEK) { chipIcon = context.getDrawable(R.drawable.ic_history); } else { // get the icon drawable with the first mimeType in chipData chipIcon = IconUtils.loadMimeIcon(context, chipData.getMimeTypes()[0]); } chip.setChipIcon(chipIcon); chip.setOnClickListener(this::onChipClick); if (mCheckedChipItems.contains(chipData)) { Loading
src/com/android/documentsui/queries/SearchViewManager.java +1 −5 Original line number Diff line number Diff line Loading @@ -162,15 +162,11 @@ public class SearchViewManager implements * @return the bundle of query arguments */ public Bundle buildQueryArgs() { final Bundle queryArgs = new Bundle(); final Bundle queryArgs = mChipViewManager.getCheckedChipQueryArgs(); if (!TextUtils.isEmpty(mCurrentSearch)) { queryArgs.putString(DocumentsContract.QUERY_ARG_DISPLAY_NAME, mCurrentSearch); } final String[] checkedMimeTypes = mChipViewManager.getCheckedMimeTypes(); if (checkedMimeTypes != null && checkedMimeTypes.length > 0) { queryArgs.putStringArray(DocumentsContract.QUERY_ARG_MIME_TYPES, checkedMimeTypes); } return queryArgs; } Loading