1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.documentsui.dirlist;
18
19import static com.android.documentsui.base.DocumentInfo.getCursorString;
20
21import android.content.Context;
22import android.database.Cursor;
23import android.provider.DocumentsContract.Document;
24import android.support.v7.widget.GridLayoutManager;
25import android.support.v7.widget.RecyclerView;
26
27import com.android.documentsui.ActionHandler;
28import com.android.documentsui.Model;
29import com.android.documentsui.base.EventListener;
30import com.android.documentsui.base.Features;
31import com.android.documentsui.base.State;
32
33import java.util.List;
34
35/**
36 * DocumentsAdapter provides glue between a directory Model, and RecylcerView. We've
37 * abstracted this a bit in order to decompose some specialized support
38 * for adding dummy layout objects (@see SectionBreakDocumentsAdapter). Handling of the
39 * dummy layout objects was error prone when interspersed with the core mode / adapter code.
40 *
41 * @see ModelBackedDocumentsAdapter
42 * @see DirectoryAddonsAdapter
43 */
44public abstract class DocumentsAdapter
45        extends RecyclerView.Adapter<DocumentHolder> {
46    // Item types used by ModelBackedDocumentsAdapter
47    public static final int ITEM_TYPE_DOCUMENT = 1;
48    public static final int ITEM_TYPE_DIRECTORY = 2;
49    // Item types used by SectionBreakDocumentsAdapterWrapper
50    public static final int ITEM_TYPE_SECTION_BREAK = Integer.MAX_VALUE;
51    public static final int ITEM_TYPE_HEADER_MESSAGE = Integer.MAX_VALUE - 1;
52    public static final int ITEM_TYPE_INFLATED_MESSAGE = Integer.MAX_VALUE - 2;
53
54    // Payloads for notifyItemChange to distinguish between selection and other events.
55    static final String SELECTION_CHANGED_MARKER = "Selection-Changed";
56
57    /**
58     * Returns a list of model IDs of items currently in the adapter.
59     *
60     * @return A list of Model IDs.
61     */
62    public abstract List<String> getModelIds();
63
64    public abstract int getAdapterPosition(String modelId);
65
66    /**
67     * Triggers item-change notifications by stable ID (as opposed to position).
68     * Passing an unrecognized ID will result in a warning in logcat, but no other error.
69     */
70    public abstract void onItemSelectionChanged(String id);
71
72    /**
73     * @return The model ID of the item at the given adapter position.
74     */
75    public abstract String getModelId(int position);
76
77    abstract EventListener<Model.Update> getModelUpdateListener();
78
79    /**
80     * Returns a class that yields the span size for a particular element. This is
81     * primarily useful in {@link DirectoryAddonsAdapter} where
82     * we adjust sizes.
83     */
84    GridLayoutManager.SpanSizeLookup createSpanSizeLookup() {
85        throw new UnsupportedOperationException();
86    }
87
88    public boolean hasModelIds() {
89        return !getModelIds().isEmpty();
90    }
91
92    static boolean isDirectory(Cursor cursor) {
93        final String mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
94        return Document.MIME_TYPE_DIR.equals(mimeType);
95    }
96
97    boolean isDirectory(Model model, int position) {
98        String modelId = getModelIds().get(position);
99        Cursor cursor = model.getItem(modelId);
100        return isDirectory(cursor);
101    }
102
103    /**
104     * Environmental access for View adapter implementations.
105     */
106    interface Environment {
107        Context getContext();
108        Features getFeatures();
109        ActionHandler getActionHandler();
110        int getColumnCount();
111        State getDisplayState();
112        boolean isInSearchMode();
113        boolean isSelected(String id);
114        Model getModel();
115        boolean isDocumentEnabled(String mimeType, int flags);
116        void initDocumentHolder(DocumentHolder holder);
117        void onBindDocumentHolder(DocumentHolder holder, Cursor cursor);
118    }
119}
120