SortModel.java revision 2010ff7828f2d68de0be24c975f5c48ec3151f96
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;
232010ff7828f2d68de0be24c975f5c48ec3151f96Garfield Tanimport android.database.Cursor;
24171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanimport android.os.Parcel;
25171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanimport android.os.Parcelable;
2611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tanimport android.provider.DocumentsContract.Document;
2711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tanimport android.util.Log;
28171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanimport android.util.SparseArray;
29171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanimport android.view.View;
30171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
31171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanimport com.android.documentsui.R;
3261f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tanimport com.android.documentsui.sorting.SortDimension.SortDirection;
33171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
34171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanimport java.lang.annotation.Retention;
35171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanimport java.lang.annotation.RetentionPolicy;
36171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanimport java.util.ArrayList;
37171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanimport java.util.Collection;
38171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanimport java.util.List;
3911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tanimport java.util.function.Consumer;
40171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
41171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan/**
42171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan * Sort model that contains all columns and their sorting state.
43171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan */
44171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tanpublic class SortModel implements Parcelable {
45171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    @IntDef({
4611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            SORT_DIMENSION_ID_UNKNOWN,
47171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan            SORT_DIMENSION_ID_TITLE,
48171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan            SORT_DIMENSION_ID_SUMMARY,
49171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan            SORT_DIMENSION_ID_DATE,
50171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan            SORT_DIMENSION_ID_SIZE
51171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    })
52171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    @Retention(RetentionPolicy.SOURCE)
53171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    public @interface SortDimensionId {}
5411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    public static final int SORT_DIMENSION_ID_UNKNOWN = 0;
55171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    public static final int SORT_DIMENSION_ID_TITLE = android.R.id.title;
56171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    public static final int SORT_DIMENSION_ID_SUMMARY = android.R.id.summary;
57171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    public static final int SORT_DIMENSION_ID_SIZE = R.id.size;
58171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    public static final int SORT_DIMENSION_ID_DATE = R.id.date;
59171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
6061f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan    @IntDef(flag = true, value = {
6161f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan            UPDATE_TYPE_NONE,
6211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            UPDATE_TYPE_UNSPECIFIED,
6311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            UPDATE_TYPE_STATUS,
6411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            UPDATE_TYPE_VISIBILITY,
6511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            UPDATE_TYPE_SORTING
6611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    })
6711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    @Retention(RetentionPolicy.SOURCE)
6811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    public @interface UpdateType {}
6911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    /**
7061f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan     * Default value for update type. Nothing is updated.
7111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan     */
7261f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan    public static final int UPDATE_TYPE_NONE = 0;
7311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    /**
7411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan     * Indicates the status of sorting has changed, i.e. whether soring is enabled.
7511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan     */
7611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    public static final int UPDATE_TYPE_STATUS = 1;
7711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    /**
7811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan     * Indicates the visibility of at least one dimension has changed.
7911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan     */
8061f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan    public static final int UPDATE_TYPE_VISIBILITY = 1 << 1;
8111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    /**
8211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan     * Indicates the sorting order has changed, either because the sorted dimension has changed or
8311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan     * the sort direction has changed.
8411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan     */
8561f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan    public static final int UPDATE_TYPE_SORTING = 1 << 2;
8661f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan    /**
8761f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan     * Anything can be changed if the type is unspecified.
8861f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan     */
8961f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan    public static final int UPDATE_TYPE_UNSPECIFIED = -1;
9011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
9111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    private static final String TAG = "SortModel";
9211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
93171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    private final SparseArray<SortDimension> mDimensions;
94171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
95171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    private transient final List<UpdateListener> mListeners;
9611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    private transient Consumer<SortDimension> mMetricRecorder;
97171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
9811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    private int mDefaultDimensionId = SORT_DIMENSION_ID_UNKNOWN;
9911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    private boolean mIsUserSpecified = false;
10011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    private @Nullable SortDimension mSortedDimension;
101171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
102171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    private boolean mIsSortEnabled = true;
103171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
104171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    public 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
149171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    public void setSortEnabled(boolean enabled) {
150171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        mIsSortEnabled = enabled;
151171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
15211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        notifyListeners(UPDATE_TYPE_STATUS);
153171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    }
154171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
155171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    public boolean isSortEnabled() {
156171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        return mIsSortEnabled;
157171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    }
158171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
15911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    /**
16011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan     * Sort by the default direction of the given dimension if user has never specified any sort
16111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan     * direction before.
16211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan     * @param dimensionId the id of the dimension
16311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan     */
16411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    public void setDefaultDimension(int dimensionId) {
16511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        final boolean mayNeedSorting = (mDefaultDimensionId != dimensionId);
16611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
16711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        mDefaultDimensionId = dimensionId;
16811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
16911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        if (mayNeedSorting) {
17011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            sortOnDefault();
17111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        }
17211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    }
17311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
17411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    void setMetricRecorder(Consumer<SortDimension> metricRecorder) {
17511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        mMetricRecorder = metricRecorder;
17611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    }
17711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
17811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    /**
17911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan     * Sort by given dimension and direction. Should only be used when user explicitly asks to sort
18011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan     * docs.
18111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan     * @param dimensionId the id of the dimension
18211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan     * @param direction the direction to sort docs in
18311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan     */
18461f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan    public void sortByUser(int dimensionId, @SortDirection int direction) {
185171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        if (!mIsSortEnabled) {
186171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan            throw new IllegalStateException("Sort is not enabled.");
187171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        }
18811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
18911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        SortDimension dimension = mDimensions.get(dimensionId);
19011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        if (dimension == null) {
19111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            throw new IllegalArgumentException("Unknown column id: " + dimensionId);
19211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        }
19311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
19411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        sortByDimension(dimension, direction);
19511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
19611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        if (mMetricRecorder != null) {
19711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            mMetricRecorder.accept(dimension);
19811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        }
19911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
20011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        mIsUserSpecified = true;
20111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    }
20211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
20311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    private void sortByDimension(
20461f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan            SortDimension newSortedDimension, @SortDirection int direction) {
20511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        if (newSortedDimension == mSortedDimension
20611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                && mSortedDimension.mSortDirection == direction) {
20711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            // Sort direction not changed, no need to proceed.
20811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            return;
209171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        }
210171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
21111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        if ((newSortedDimension.getSortCapability() & direction) == 0) {
212171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan            throw new IllegalStateException(
21311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                    "Dimension with id: " + newSortedDimension.getId()
21411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                    + " can't be sorted in direction:" + direction);
215171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        }
21611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
217171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        switch (direction) {
218171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan            case SortDimension.SORT_DIRECTION_ASCENDING:
219171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan            case SortDimension.SORT_DIRECTION_DESCENDING:
220171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                newSortedDimension.mSortDirection = direction;
221171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                break;
222171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan            default:
223171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                throw new IllegalArgumentException("Unknown sort direction: " + direction);
224171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        }
225171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
226171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        if (mSortedDimension != null && mSortedDimension != newSortedDimension) {
227171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan            mSortedDimension.mSortDirection = SortDimension.SORT_DIRECTION_NONE;
228171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        }
229171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
230171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        mSortedDimension = newSortedDimension;
231171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
23211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        notifyListeners(UPDATE_TYPE_SORTING);
233171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    }
234171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
235171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    public void setDimensionVisibility(int columnId, int visibility) {
236171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        assert(mDimensions.get(columnId) != null);
237171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
238171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        mDimensions.get(columnId).mVisibility = visibility;
239171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
24011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        notifyListeners(UPDATE_TYPE_VISIBILITY);
24111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    }
24211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
2432010ff7828f2d68de0be24c975f5c48ec3151f96Garfield Tan    public Cursor sortCursor(Cursor cursor) {
2442010ff7828f2d68de0be24c975f5c48ec3151f96Garfield Tan        if (mSortedDimension != null) {
2452010ff7828f2d68de0be24c975f5c48ec3151f96Garfield Tan            return new SortingCursorWrapper(cursor, mSortedDimension);
2462010ff7828f2d68de0be24c975f5c48ec3151f96Garfield Tan        } else {
2472010ff7828f2d68de0be24c975f5c48ec3151f96Garfield Tan            return cursor;
2482010ff7828f2d68de0be24c975f5c48ec3151f96Garfield Tan        }
2492010ff7828f2d68de0be24c975f5c48ec3151f96Garfield Tan    }
2502010ff7828f2d68de0be24c975f5c48ec3151f96Garfield Tan
25111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    public @Nullable String getDocumentSortQuery() {
25211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        final int id = getSortedDimensionId();
25311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        final String columnName;
25411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        switch (id) {
25561f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan            case SORT_DIMENSION_ID_UNKNOWN:
25611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                return null;
25711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            case SortModel.SORT_DIMENSION_ID_TITLE:
25811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                columnName = Document.COLUMN_DISPLAY_NAME;
25911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                break;
26011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            case SortModel.SORT_DIMENSION_ID_DATE:
26111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                columnName = Document.COLUMN_LAST_MODIFIED;
26211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                break;
26311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            case SortModel.SORT_DIMENSION_ID_SIZE:
26411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                columnName = Document.COLUMN_SIZE;
26511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                break;
26611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            default:
26711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                throw new IllegalStateException(
26811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                        "Unexpected sort dimension id: " + id);
26911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        }
27011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
27111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        final SortDimension dimension = getDimensionById(id);
27211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        final String direction;
27311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        switch (dimension.getSortDirection()) {
27411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            case SortDimension.SORT_DIRECTION_ASCENDING:
27511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                direction = " ASC";
27611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                break;
27711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            case SortDimension.SORT_DIRECTION_DESCENDING:
27811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                direction = " DESC";
27911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                break;
28011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            default:
28111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                throw new IllegalStateException(
28211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                        "Unexpected sort direction: " + dimension.getSortDirection());
28311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        }
28411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
28511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        return columnName + direction;
286171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    }
287171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
28811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    private void notifyListeners(@UpdateType int updateType) {
289171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        for (int i = mListeners.size() - 1; i >= 0; --i) {
29011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            mListeners.get(i).onModelUpdate(this, updateType);
291171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        }
292171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    }
293171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
294171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    public void addListener(UpdateListener listener) {
295171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        mListeners.add(listener);
296171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    }
297171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
298171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    public void removeListener(UpdateListener listener) {
299171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        mListeners.remove(listener);
300171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    }
301171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
302171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    public void clearSortDirection() {
303171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        if (mSortedDimension != null) {
304171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan            mSortedDimension.mSortDirection = SortDimension.SORT_DIRECTION_NONE;
305171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan            mSortedDimension = null;
306171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        }
30711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
30811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        mIsUserSpecified = false;
30911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
31011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        sortOnDefault();
31111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    }
31211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
31311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    /**
31411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan     * Sort by default dimension and direction if there is no history of user specifying a sort
31511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan     * order.
31611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan     */
31711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    private void sortOnDefault() {
31811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        if (!mIsUserSpecified) {
31911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            SortDimension dimension = mDimensions.get(mDefaultDimensionId);
32011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            if (dimension == null) {
32111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                if (DEBUG) Log.d(TAG, "No default sort dimension.");
32211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                return;
32311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            }
32411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
32511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            sortByDimension(dimension, dimension.getDefaultSortDirection());
32611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        }
32711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    }
32811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
32911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    @Override
33011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    public boolean equals(Object o) {
33111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        if (o == null || !(o instanceof SortModel)) {
33211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            return false;
33311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        }
33411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
33511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        if (this == o) {
33611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            return true;
33711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        }
33811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
33911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        SortModel other = (SortModel) o;
34011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        if (mDimensions.size() != other.mDimensions.size()) {
34111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            return false;
34211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        }
34311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        for (int i = 0; i < mDimensions.size(); ++i) {
34411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            final SortDimension dimension = mDimensions.valueAt(i);
34511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            final int id = dimension.getId();
34611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            if (!dimension.equals(other.getDimensionById(id))) {
34711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                return false;
34811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            }
34911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        }
35011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
35111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        return mDefaultDimensionId == other.mDefaultDimensionId
35211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                && mIsSortEnabled == other.mIsSortEnabled
35311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                && (mSortedDimension == other.mSortedDimension
35411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                    || mSortedDimension.equals(other.mSortedDimension));
35511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    }
35611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
35711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    @Override
35811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan    public String toString() {
35911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        return new StringBuilder()
36011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                .append("SortModel{")
36111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                .append("enabled=").append(mIsSortEnabled)
36211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                .append(", dimensions=").append(mDimensions)
36311d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                .append(", defaultDimensionId=").append(mDefaultDimensionId)
36411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                .append(", sortedDimension=").append(mSortedDimension)
36511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                .append("}")
36611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                .toString();
367171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    }
368171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
369171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    @Override
370171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    public int describeContents() {
371171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        return 0;
372171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    }
373171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
374171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    @Override
375171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    public void writeToParcel(Parcel out, int flag) {
376171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        out.writeInt(mDimensions.size());
377171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        for (int i = 0; i < mDimensions.size(); ++i) {
378171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan            out.writeParcelable(mDimensions.valueAt(i), flag);
379171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        }
38011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
38111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        out.writeInt(mDefaultDimensionId);
38211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        out.writeInt(mIsSortEnabled ? 1 : 0);
38361f564beacafc5edebbb4b05d098203816ff7f64Garfield, Tan        out.writeInt(getSortedDimensionId());
384171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    }
385171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
386171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    public static Parcelable.Creator<SortModel> CREATOR = new Parcelable.Creator<SortModel>() {
387171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
388171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        @Override
389171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        public SortModel createFromParcel(Parcel in) {
39011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            final int size = in.readInt();
391171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan            Collection<SortDimension> columns = new ArrayList<>(size);
392171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan            for (int i = 0; i < size; ++i) {
393171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                columns.add(in.readParcelable(getClass().getClassLoader()));
394171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan            }
39511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            SortModel model = new SortModel(columns);
39611d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
39711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            model.mDefaultDimensionId = in.readInt();
39811d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            model.mIsSortEnabled = (in.readInt() == 1);
39911d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            model.mSortedDimension = model.getDimensionById(in.readInt());
40011d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan
40111d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan            return model;
402171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        }
403171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
404171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        @Override
405171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        public SortModel[] newArray(int size) {
406171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan            return new SortModel[size];
407171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        }
408171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    };
409171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
410171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    /**
411171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan     * Creates a model for all other roots.
412171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan     *
413171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan     * TODO: move definition of columns into xml, and inflate model from it.
414171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan     */
415171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    public static SortModel createModel() {
416171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        List<SortDimension> dimensions = new ArrayList<>(4);
417171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        SortDimension.Builder builder = new SortDimension.Builder();
418171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
419171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        // Name column
420171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        dimensions.add(builder
421171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                .withId(SORT_DIMENSION_ID_TITLE)
42211d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                .withLabelId(R.string.sort_dimension_name)
423171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                .withDataType(SortDimension.DATA_TYPE_STRING)
424171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                .withSortCapability(SortDimension.SORT_CAPABILITY_BOTH_DIRECTION)
425171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                .withDefaultSortDirection(SortDimension.SORT_DIRECTION_ASCENDING)
426171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                .withVisibility(View.VISIBLE)
427171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                .build()
428171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        );
429171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
430171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        // Summary column
431171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        // Summary is only visible in Downloads and Recents root.
432171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        dimensions.add(builder
433171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                .withId(SORT_DIMENSION_ID_SUMMARY)
43411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                .withLabelId(R.string.sort_dimension_summary)
435171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                .withDataType(SortDimension.DATA_TYPE_STRING)
436171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                .withSortCapability(SortDimension.SORT_CAPABILITY_NONE)
437171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                .withVisibility(View.INVISIBLE)
438171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                .build()
439171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        );
440171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
441171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        // Size column
442171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        dimensions.add(builder
443171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                .withId(SORT_DIMENSION_ID_SIZE)
44411d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                .withLabelId(R.string.sort_dimension_size)
445171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                .withDataType(SortDimension.DATA_TYPE_NUMBER)
446171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                .withSortCapability(SortDimension.SORT_CAPABILITY_BOTH_DIRECTION)
447171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                .withDefaultSortDirection(SortDimension.SORT_DIRECTION_ASCENDING)
448171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                .withVisibility(View.VISIBLE)
449171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                .build()
450171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        );
451171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
452171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        // Date column
453171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        dimensions.add(builder
454171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                .withId(SORT_DIMENSION_ID_DATE)
45511d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan                .withLabelId(R.string.sort_dimension_date)
456171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                .withDataType(SortDimension.DATA_TYPE_NUMBER)
457171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                .withSortCapability(SortDimension.SORT_CAPABILITY_BOTH_DIRECTION)
458171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                .withDefaultSortDirection(SortDimension.SORT_DIRECTION_DESCENDING)
459171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                .withVisibility(View.VISIBLE)
460171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan                .build()
461171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        );
462171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
463171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan        return new SortModel(dimensions);
464171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    }
465171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan
466171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    public interface UpdateListener {
46711d23483bf28768c04c25e4056df648fa8301aefGarfield, Tan        void onModelUpdate(SortModel newModel, @UpdateType int updateType);
468171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan    }
469171e6f53d114c3fe5ee69bc4e2bafb53daa4bda5Garfield, Tan}
470