1171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan/* 2171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan * Copyright (C) 2016 The Android Open Source Project 3171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan * 4171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan * Licensed under the Apache License, Version 2.0 (the "License"); 5171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan * you may not use this file except in compliance with the License. 6171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan * You may obtain a copy of the License at 7171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan * 8171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan * http://www.apache.org/licenses/LICENSE-2.0 9171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan * 10171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan * Unless required by applicable law or agreed to in writing, software 11171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan * distributed under the License is distributed on an "AS IS" BASIS, 12171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan * See the License for the specific language governing permissions and 14171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan * limitations under the License. 15171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan */ 16171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 17171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanpackage com.android.documentsui.sorting; 18171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 19d9caa6ab53aa784acaf241c0ded3c4ae2d342bf8Steve McKayimport static com.android.documentsui.base.Shared.DEBUG; 2011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan 21171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanimport android.annotation.IntDef; 2211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tanimport android.annotation.Nullable; 23a4b68e5b5917c93c3f3c185ecd42db2596119220Steve McKayimport android.content.ContentResolver; 242010ff7828f2d68de0be24c975f5c48ec3151f96Garfield Tanimport android.database.Cursor; 2550b9baedc04a226b7a2e21f81f9a87533e3f7d02Steve McKayimport android.os.Bundle; 26171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanimport android.os.Parcel; 27171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanimport android.os.Parcelable; 2811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tanimport android.provider.DocumentsContract.Document; 29b47b4b560c46336a0e6ba3e86db3f2d76b4b2bc3Garfield Tanimport android.support.annotation.VisibleForTesting; 3011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tanimport android.util.Log; 31171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanimport android.util.SparseArray; 32171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanimport android.view.View; 33171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 34171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanimport com.android.documentsui.R; 35b47b4b560c46336a0e6ba3e86db3f2d76b4b2bc3Garfield Tanimport com.android.documentsui.base.Lookup; 3661f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tanimport com.android.documentsui.sorting.SortDimension.SortDirection; 37171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 38171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanimport java.lang.annotation.Retention; 39171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanimport java.lang.annotation.RetentionPolicy; 40171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanimport java.util.ArrayList; 41171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanimport java.util.Collection; 42171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanimport java.util.List; 4311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tanimport java.util.function.Consumer; 44171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 45171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan/** 46171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan * Sort model that contains all columns and their sorting state. 47171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan */ 48171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanpublic class SortModel implements Parcelable { 49171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan @IntDef({ 5011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan SORT_DIMENSION_ID_UNKNOWN, 51171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan SORT_DIMENSION_ID_TITLE, 52171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan SORT_DIMENSION_ID_SUMMARY, 53b47b4b560c46336a0e6ba3e86db3f2d76b4b2bc3Garfield Tan SORT_DIMENSION_ID_SIZE, 54b47b4b560c46336a0e6ba3e86db3f2d76b4b2bc3Garfield Tan SORT_DIMENSION_ID_FILE_TYPE, 55b47b4b560c46336a0e6ba3e86db3f2d76b4b2bc3Garfield Tan SORT_DIMENSION_ID_DATE 56171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan }) 57171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan @Retention(RetentionPolicy.SOURCE) 58171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan public @interface SortDimensionId {} 5911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan public static final int SORT_DIMENSION_ID_UNKNOWN = 0; 60171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan public static final int SORT_DIMENSION_ID_TITLE = android.R.id.title; 61171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan public static final int SORT_DIMENSION_ID_SUMMARY = android.R.id.summary; 62171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan public static final int SORT_DIMENSION_ID_SIZE = R.id.size; 63b47b4b560c46336a0e6ba3e86db3f2d76b4b2bc3Garfield Tan public static final int SORT_DIMENSION_ID_FILE_TYPE = R.id.file_type; 64171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan public static final int SORT_DIMENSION_ID_DATE = R.id.date; 65171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 6661f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan @IntDef(flag = true, value = { 6761f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan UPDATE_TYPE_NONE, 6811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan UPDATE_TYPE_UNSPECIFIED, 6911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan UPDATE_TYPE_VISIBILITY, 7011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan UPDATE_TYPE_SORTING 7111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan }) 7211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan @Retention(RetentionPolicy.SOURCE) 7311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan public @interface UpdateType {} 7411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan /** 7561f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan * Default value for update type. Nothing is updated. 7611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan */ 7761f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan public static final int UPDATE_TYPE_NONE = 0; 7811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan /** 7911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan * Indicates the visibility of at least one dimension has changed. 8011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan */ 81fe199cb1ae0a443c65111ee80daa05b9fafc48a6Garfield Tan public static final int UPDATE_TYPE_VISIBILITY = 1; 8211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan /** 8311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan * Indicates the sorting order has changed, either because the sorted dimension has changed or 8411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan * the sort direction has changed. 8511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan */ 86fe199cb1ae0a443c65111ee80daa05b9fafc48a6Garfield Tan public static final int UPDATE_TYPE_SORTING = 1 << 1; 8761f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan /** 8861f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan * Anything can be changed if the type is unspecified. 8961f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan */ 9061f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan public static final int UPDATE_TYPE_UNSPECIFIED = -1; 9111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan 9211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan private static final String TAG = "SortModel"; 9311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan 94171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan private final SparseArray<SortDimension> mDimensions; 95171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 96171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan private transient final List<UpdateListener> mListeners; 9711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan private transient Consumer<SortDimension> mMetricRecorder; 98171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 9911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan private int mDefaultDimensionId = SORT_DIMENSION_ID_UNKNOWN; 10011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan private boolean mIsUserSpecified = false; 10111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan private @Nullable SortDimension mSortedDimension; 102171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 103b47b4b560c46336a0e6ba3e86db3f2d76b4b2bc3Garfield Tan @VisibleForTesting 104b47b4b560c46336a0e6ba3e86db3f2d76b4b2bc3Garfield Tan SortModel(Collection<SortDimension> columns) { 105171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan mDimensions = new SparseArray<>(columns.size()); 106171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 107171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan for (SortDimension column : columns) { 10811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan if (column.getId() == SORT_DIMENSION_ID_UNKNOWN) { 10911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan throw new IllegalArgumentException( 11011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan "SortDimension id can't be " + SORT_DIMENSION_ID_UNKNOWN + "."); 11111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan } 112171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan if (mDimensions.get(column.getId()) != null) { 113171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan throw new IllegalStateException( 114171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan "SortDimension id must be unique. Duplicate id: " + column.getId()); 115171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 116171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan mDimensions.put(column.getId(), column); 117171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 118171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 119171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan mListeners = new ArrayList<>(); 120171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 121171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 122171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan public int getSize() { 123171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan return mDimensions.size(); 124171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 125171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 126171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan public SortDimension getDimensionAt(int index) { 127171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan return mDimensions.valueAt(index); 128171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 129171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 13011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan public @Nullable SortDimension getDimensionById(int id) { 131171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan return mDimensions.get(id); 132171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 133171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 13411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan /** 13511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan * Gets the sorted dimension id. 13611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan * @return the sorted dimension id or {@link #SORT_DIMENSION_ID_UNKNOWN} if there is no sorted 13711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan * dimension. 13811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan */ 13911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan public int getSortedDimensionId() { 14011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan return mSortedDimension != null ? mSortedDimension.getId() : SORT_DIMENSION_ID_UNKNOWN; 141171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 142171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 14361f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan public @SortDirection int getCurrentSortDirection() { 14461f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan return mSortedDimension != null 14561f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan ? mSortedDimension.getSortDirection() 14661f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan : SortDimension.SORT_DIRECTION_NONE; 14761f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan } 14861f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan 14911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan /** 15011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan * Sort by the default direction of the given dimension if user has never specified any sort 15111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan * direction before. 15211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan * @param dimensionId the id of the dimension 15311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan */ 15411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan public void setDefaultDimension(int dimensionId) { 15511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan final boolean mayNeedSorting = (mDefaultDimensionId != dimensionId); 15611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan 15711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan mDefaultDimensionId = dimensionId; 15811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan 15911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan if (mayNeedSorting) { 16011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan sortOnDefault(); 16111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan } 16211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan } 16311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan 16411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan void setMetricRecorder(Consumer<SortDimension> metricRecorder) { 16511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan mMetricRecorder = metricRecorder; 16611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan } 16711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan 16811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan /** 16911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan * Sort by given dimension and direction. Should only be used when user explicitly asks to sort 17011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan * docs. 17111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan * @param dimensionId the id of the dimension 17211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan * @param direction the direction to sort docs in 17311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan */ 17461f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan public void sortByUser(int dimensionId, @SortDirection int direction) { 17511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan SortDimension dimension = mDimensions.get(dimensionId); 17611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan if (dimension == null) { 17711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan throw new IllegalArgumentException("Unknown column id: " + dimensionId); 17811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan } 17911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan 18011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan sortByDimension(dimension, direction); 18111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan 18211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan if (mMetricRecorder != null) { 18311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan mMetricRecorder.accept(dimension); 18411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan } 18511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan 18611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan mIsUserSpecified = true; 18711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan } 18811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan 18911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan private void sortByDimension( 19061f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan SortDimension newSortedDimension, @SortDirection int direction) { 19111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan if (newSortedDimension == mSortedDimension 19211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan && mSortedDimension.mSortDirection == direction) { 19311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan // Sort direction not changed, no need to proceed. 19411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan return; 195171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 196171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 19711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan if ((newSortedDimension.getSortCapability() & direction) == 0) { 198171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan throw new IllegalStateException( 19911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan "Dimension with id: " + newSortedDimension.getId() 20011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan + " can't be sorted in direction:" + direction); 201171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 20211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan 203171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan switch (direction) { 204171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan case SortDimension.SORT_DIRECTION_ASCENDING: 205171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan case SortDimension.SORT_DIRECTION_DESCENDING: 206171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan newSortedDimension.mSortDirection = direction; 207171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan break; 208171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan default: 209171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan throw new IllegalArgumentException("Unknown sort direction: " + direction); 210171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 211171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 212171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan if (mSortedDimension != null && mSortedDimension != newSortedDimension) { 213171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan mSortedDimension.mSortDirection = SortDimension.SORT_DIRECTION_NONE; 214171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 215171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 216171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan mSortedDimension = newSortedDimension; 217171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 21811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan notifyListeners(UPDATE_TYPE_SORTING); 219171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 220171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 221171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan public void setDimensionVisibility(int columnId, int visibility) { 222171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan assert(mDimensions.get(columnId) != null); 223171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 224171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan mDimensions.get(columnId).mVisibility = visibility; 225171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 22611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan notifyListeners(UPDATE_TYPE_VISIBILITY); 22711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan } 22811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan 229b47b4b560c46336a0e6ba3e86db3f2d76b4b2bc3Garfield Tan public Cursor sortCursor(Cursor cursor, Lookup<String, String> fileTypesMap) { 2302010ff7828f2d68de0be24c975f5c48ec3151f96Garfield Tan if (mSortedDimension != null) { 231b47b4b560c46336a0e6ba3e86db3f2d76b4b2bc3Garfield Tan return new SortingCursorWrapper(cursor, mSortedDimension, fileTypesMap); 2322010ff7828f2d68de0be24c975f5c48ec3151f96Garfield Tan } else { 2332010ff7828f2d68de0be24c975f5c48ec3151f96Garfield Tan return cursor; 2342010ff7828f2d68de0be24c975f5c48ec3151f96Garfield Tan } 2352010ff7828f2d68de0be24c975f5c48ec3151f96Garfield Tan } 2362010ff7828f2d68de0be24c975f5c48ec3151f96Garfield Tan 23750b9baedc04a226b7a2e21f81f9a87533e3f7d02Steve McKay public void addQuerySortArgs(Bundle queryArgs) { 23898f8c5f502e049a6b85439d773949cdbaa0f78aeSteve McKay // should only be called when R.bool.feature_content_paging is true 23950b9baedc04a226b7a2e21f81f9a87533e3f7d02Steve McKay 24011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan final int id = getSortedDimensionId(); 24111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan switch (id) { 24261f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan case SORT_DIMENSION_ID_UNKNOWN: 24350b9baedc04a226b7a2e21f81f9a87533e3f7d02Steve McKay return; 24411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan case SortModel.SORT_DIMENSION_ID_TITLE: 24550b9baedc04a226b7a2e21f81f9a87533e3f7d02Steve McKay queryArgs.putStringArray( 24650b9baedc04a226b7a2e21f81f9a87533e3f7d02Steve McKay ContentResolver.QUERY_ARG_SORT_COLUMNS, 24750b9baedc04a226b7a2e21f81f9a87533e3f7d02Steve McKay new String[]{ Document.COLUMN_DISPLAY_NAME }); 24811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan break; 24911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan case SortModel.SORT_DIMENSION_ID_DATE: 25050b9baedc04a226b7a2e21f81f9a87533e3f7d02Steve McKay queryArgs.putStringArray( 25150b9baedc04a226b7a2e21f81f9a87533e3f7d02Steve McKay ContentResolver.QUERY_ARG_SORT_COLUMNS, 25250b9baedc04a226b7a2e21f81f9a87533e3f7d02Steve McKay new String[]{ Document.COLUMN_LAST_MODIFIED }); 25311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan break; 25411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan case SortModel.SORT_DIMENSION_ID_SIZE: 25550b9baedc04a226b7a2e21f81f9a87533e3f7d02Steve McKay queryArgs.putStringArray( 25650b9baedc04a226b7a2e21f81f9a87533e3f7d02Steve McKay ContentResolver.QUERY_ARG_SORT_COLUMNS, 25750b9baedc04a226b7a2e21f81f9a87533e3f7d02Steve McKay new String[]{ Document.COLUMN_SIZE }); 25811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan break; 25998d745d90b2bf8232593f2d5f9092536298d1147Garfield Tan case SortModel.SORT_DIMENSION_ID_FILE_TYPE: 26098d745d90b2bf8232593f2d5f9092536298d1147Garfield Tan // Unfortunately sorting by mime type is pretty much guaranteed different from 26198d745d90b2bf8232593f2d5f9092536298d1147Garfield Tan // sorting by user-friendly type, so there is no point to guide the provider to sort 26298d745d90b2bf8232593f2d5f9092536298d1147Garfield Tan // in a particular order. 26398d745d90b2bf8232593f2d5f9092536298d1147Garfield Tan return; 26411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan default: 26511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan throw new IllegalStateException( 26611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan "Unexpected sort dimension id: " + id); 26711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan } 26811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan 26911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan final SortDimension dimension = getDimensionById(id); 27011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan switch (dimension.getSortDirection()) { 27111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan case SortDimension.SORT_DIRECTION_ASCENDING: 27250b9baedc04a226b7a2e21f81f9a87533e3f7d02Steve McKay queryArgs.putInt( 27350b9baedc04a226b7a2e21f81f9a87533e3f7d02Steve McKay ContentResolver.QUERY_ARG_SORT_DIRECTION, 27450b9baedc04a226b7a2e21f81f9a87533e3f7d02Steve McKay ContentResolver.QUERY_SORT_DIRECTION_ASCENDING); 27511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan break; 27611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan case SortDimension.SORT_DIRECTION_DESCENDING: 27750b9baedc04a226b7a2e21f81f9a87533e3f7d02Steve McKay queryArgs.putInt( 27850b9baedc04a226b7a2e21f81f9a87533e3f7d02Steve McKay ContentResolver.QUERY_ARG_SORT_DIRECTION, 27950b9baedc04a226b7a2e21f81f9a87533e3f7d02Steve McKay ContentResolver.QUERY_SORT_DIRECTION_DESCENDING); 28011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan break; 28111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan default: 28211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan throw new IllegalStateException( 28311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan "Unexpected sort direction: " + dimension.getSortDirection()); 28411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan } 285171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 286171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 287f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay public @Nullable String getDocumentSortQuery() { 288710248d5ee766765b86fa36fe2ddd8d65f926755Steve McKay // This method should only be called when R.bool.feature_content_paging exists. 289710248d5ee766765b86fa36fe2ddd8d65f926755Steve McKay // Once that feature is enabled by default (and reference removed), this method 290710248d5ee766765b86fa36fe2ddd8d65f926755Steve McKay // should also be removed. 291710248d5ee766765b86fa36fe2ddd8d65f926755Steve McKay // The following log message exists simply to make reference to 292710248d5ee766765b86fa36fe2ddd8d65f926755Steve McKay // R.bool.feature_content_paging so that compiler will fail when value 293710248d5ee766765b86fa36fe2ddd8d65f926755Steve McKay // is remove from config.xml. 2945918a06c126f3554d33b0b36a0b4c21f3dbc91beSteve McKay int readTheCommentAbove = R.bool.feature_content_paging; 295f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay 296f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay final int id = getSortedDimensionId(); 297f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay final String columnName; 298f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay switch (id) { 299f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay case SORT_DIMENSION_ID_UNKNOWN: 300f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay return null; 301f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay case SortModel.SORT_DIMENSION_ID_TITLE: 302f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay columnName = Document.COLUMN_DISPLAY_NAME; 303f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay break; 304f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay case SortModel.SORT_DIMENSION_ID_DATE: 305f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay columnName = Document.COLUMN_LAST_MODIFIED; 306f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay break; 307f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay case SortModel.SORT_DIMENSION_ID_SIZE: 308f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay columnName = Document.COLUMN_SIZE; 309f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay break; 31098d745d90b2bf8232593f2d5f9092536298d1147Garfield Tan case SortModel.SORT_DIMENSION_ID_FILE_TYPE: 31198d745d90b2bf8232593f2d5f9092536298d1147Garfield Tan // Unfortunately sorting by mime type is pretty much guaranteed different from 31298d745d90b2bf8232593f2d5f9092536298d1147Garfield Tan // sorting by user-friendly type, so there is no point to guide the provider to sort 31398d745d90b2bf8232593f2d5f9092536298d1147Garfield Tan // in a particular order. 31498d745d90b2bf8232593f2d5f9092536298d1147Garfield Tan return null; 315f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay default: 316f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay throw new IllegalStateException( 317f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay "Unexpected sort dimension id: " + id); 318f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay } 319f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay 320f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay final SortDimension dimension = getDimensionById(id); 321f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay final String direction; 322f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay switch (dimension.getSortDirection()) { 323f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay case SortDimension.SORT_DIRECTION_ASCENDING: 324f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay direction = " ASC"; 325f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay break; 326f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay case SortDimension.SORT_DIRECTION_DESCENDING: 327f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay direction = " DESC"; 328f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay break; 329f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay default: 330f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay throw new IllegalStateException( 331f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay "Unexpected sort direction: " + dimension.getSortDirection()); 332f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay } 333f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay 334f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay return columnName + direction; 335f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay } 336f208d84542605c76a060e3a2e76166bbd940b3bbSteve McKay 33711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan private void notifyListeners(@UpdateType int updateType) { 338171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan for (int i = mListeners.size() - 1; i >= 0; --i) { 33911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan mListeners.get(i).onModelUpdate(this, updateType); 340171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 341171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 342171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 343171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan public void addListener(UpdateListener listener) { 344171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan mListeners.add(listener); 345171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 346171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 347171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan public void removeListener(UpdateListener listener) { 348171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan mListeners.remove(listener); 349171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 350171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 35111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan /** 35211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan * Sort by default dimension and direction if there is no history of user specifying a sort 35311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan * order. 35411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan */ 35511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan private void sortOnDefault() { 35611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan if (!mIsUserSpecified) { 35711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan SortDimension dimension = mDimensions.get(mDefaultDimensionId); 35811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan if (dimension == null) { 35911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan if (DEBUG) Log.d(TAG, "No default sort dimension."); 36011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan return; 36111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan } 36211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan 36311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan sortByDimension(dimension, dimension.getDefaultSortDirection()); 36411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan } 36511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan } 36611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan 36711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan @Override 36811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan public boolean equals(Object o) { 36911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan if (o == null || !(o instanceof SortModel)) { 37011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan return false; 37111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan } 37211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan 37311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan if (this == o) { 37411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan return true; 37511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan } 37611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan 37711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan SortModel other = (SortModel) o; 37811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan if (mDimensions.size() != other.mDimensions.size()) { 37911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan return false; 38011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan } 38111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan for (int i = 0; i < mDimensions.size(); ++i) { 38211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan final SortDimension dimension = mDimensions.valueAt(i); 38311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan final int id = dimension.getId(); 38411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan if (!dimension.equals(other.getDimensionById(id))) { 38511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan return false; 38611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan } 38711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan } 38811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan 38911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan return mDefaultDimensionId == other.mDefaultDimensionId 39011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan && (mSortedDimension == other.mSortedDimension 39111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan || mSortedDimension.equals(other.mSortedDimension)); 39211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan } 39311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan 39411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan @Override 39511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan public String toString() { 39611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan return new StringBuilder() 39711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan .append("SortModel{") 398fe199cb1ae0a443c65111ee80daa05b9fafc48a6Garfield Tan .append("dimensions=").append(mDimensions) 39911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan .append(", defaultDimensionId=").append(mDefaultDimensionId) 40011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan .append(", sortedDimension=").append(mSortedDimension) 40111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan .append("}") 40211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan .toString(); 403171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 404171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 405171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan @Override 406171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan public int describeContents() { 407171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan return 0; 408171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 409171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 410171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan @Override 411171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan public void writeToParcel(Parcel out, int flag) { 412171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan out.writeInt(mDimensions.size()); 413171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan for (int i = 0; i < mDimensions.size(); ++i) { 414171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan out.writeParcelable(mDimensions.valueAt(i), flag); 415171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 41611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan 41711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan out.writeInt(mDefaultDimensionId); 41861f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan out.writeInt(getSortedDimensionId()); 419171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 420171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 421171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan public static Parcelable.Creator<SortModel> CREATOR = new Parcelable.Creator<SortModel>() { 422171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 423171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan @Override 424171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan public SortModel createFromParcel(Parcel in) { 42511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan final int size = in.readInt(); 426171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan Collection<SortDimension> columns = new ArrayList<>(size); 427171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan for (int i = 0; i < size; ++i) { 428171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan columns.add(in.readParcelable(getClass().getClassLoader())); 429171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 43011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan SortModel model = new SortModel(columns); 43111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan 43211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan model.mDefaultDimensionId = in.readInt(); 43311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan model.mSortedDimension = model.getDimensionById(in.readInt()); 43411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan 43511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan return model; 436171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 437171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 438171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan @Override 439171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan public SortModel[] newArray(int size) { 440171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan return new SortModel[size]; 441171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 442171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan }; 443171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 444171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan /** 445171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan * Creates a model for all other roots. 446171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan * 447171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan * TODO: move definition of columns into xml, and inflate model from it. 448171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan */ 449171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan public static SortModel createModel() { 450171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan List<SortDimension> dimensions = new ArrayList<>(4); 451171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan SortDimension.Builder builder = new SortDimension.Builder(); 452171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 453171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan // Name column 454171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan dimensions.add(builder 455171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan .withId(SORT_DIMENSION_ID_TITLE) 45611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan .withLabelId(R.string.sort_dimension_name) 457171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan .withDataType(SortDimension.DATA_TYPE_STRING) 458171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan .withSortCapability(SortDimension.SORT_CAPABILITY_BOTH_DIRECTION) 459171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan .withDefaultSortDirection(SortDimension.SORT_DIRECTION_ASCENDING) 460171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan .withVisibility(View.VISIBLE) 461171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan .build() 462171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan ); 463171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 464171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan // Summary column 465171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan // Summary is only visible in Downloads and Recents root. 466171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan dimensions.add(builder 467171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan .withId(SORT_DIMENSION_ID_SUMMARY) 46811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan .withLabelId(R.string.sort_dimension_summary) 469171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan .withDataType(SortDimension.DATA_TYPE_STRING) 470171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan .withSortCapability(SortDimension.SORT_CAPABILITY_NONE) 471171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan .withVisibility(View.INVISIBLE) 472171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan .build() 473171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan ); 474171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 475171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan // Size column 476171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan dimensions.add(builder 477171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan .withId(SORT_DIMENSION_ID_SIZE) 47811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan .withLabelId(R.string.sort_dimension_size) 479171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan .withDataType(SortDimension.DATA_TYPE_NUMBER) 480171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan .withSortCapability(SortDimension.SORT_CAPABILITY_BOTH_DIRECTION) 481171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan .withDefaultSortDirection(SortDimension.SORT_DIRECTION_ASCENDING) 482171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan .withVisibility(View.VISIBLE) 483171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan .build() 484171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan ); 485171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 486b47b4b560c46336a0e6ba3e86db3f2d76b4b2bc3Garfield Tan // Type column 487b47b4b560c46336a0e6ba3e86db3f2d76b4b2bc3Garfield Tan dimensions.add(builder 488b47b4b560c46336a0e6ba3e86db3f2d76b4b2bc3Garfield Tan .withId(SORT_DIMENSION_ID_FILE_TYPE) 489b47b4b560c46336a0e6ba3e86db3f2d76b4b2bc3Garfield Tan .withLabelId(R.string.sort_dimension_file_type) 490b47b4b560c46336a0e6ba3e86db3f2d76b4b2bc3Garfield Tan .withDataType(SortDimension.DATA_TYPE_STRING) 491b47b4b560c46336a0e6ba3e86db3f2d76b4b2bc3Garfield Tan .withSortCapability(SortDimension.SORT_CAPABILITY_BOTH_DIRECTION) 492b47b4b560c46336a0e6ba3e86db3f2d76b4b2bc3Garfield Tan .withDefaultSortDirection(SortDimension.SORT_DIRECTION_ASCENDING) 493b47b4b560c46336a0e6ba3e86db3f2d76b4b2bc3Garfield Tan .withVisibility(View.VISIBLE) 494b47b4b560c46336a0e6ba3e86db3f2d76b4b2bc3Garfield Tan .build()); 495b47b4b560c46336a0e6ba3e86db3f2d76b4b2bc3Garfield Tan 496171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan // Date column 497171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan dimensions.add(builder 498171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan .withId(SORT_DIMENSION_ID_DATE) 49911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan .withLabelId(R.string.sort_dimension_date) 500171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan .withDataType(SortDimension.DATA_TYPE_NUMBER) 501171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan .withSortCapability(SortDimension.SORT_CAPABILITY_BOTH_DIRECTION) 502171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan .withDefaultSortDirection(SortDimension.SORT_DIRECTION_DESCENDING) 503171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan .withVisibility(View.VISIBLE) 504171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan .build() 505171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan ); 506171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 507171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan return new SortModel(dimensions); 508171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 509171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan 510171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan public interface UpdateListener { 51111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan void onModelUpdate(SortModel newModel, @UpdateType int updateType); 512171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan } 513171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan} 514