blob: 1e080bf7aa5c96bc20c42cffb597a3adc3325f72 [file] [log] [blame]
Steve McKayc5ecf892015-12-22 18:15:31 -08001/*
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
Steve McKayd0805062016-09-15 14:30:38 -070019import static com.android.documentsui.base.DocumentInfo.getCursorInt;
20import static com.android.documentsui.base.DocumentInfo.getCursorString;
Steve McKayd9caa6a2016-09-15 16:36:45 -070021import static com.android.documentsui.base.State.MODE_GRID;
22import static com.android.documentsui.base.State.MODE_LIST;
Steve McKayc5ecf892015-12-22 18:15:31 -080023
24import android.database.Cursor;
25import android.provider.DocumentsContract.Document;
Steve McKayc5ecf892015-12-22 18:15:31 -080026import android.util.Log;
Steve McKayc5ecf892015-12-22 18:15:31 -080027import android.view.ViewGroup;
28
Garfield Tane9670332017-03-06 18:33:23 -080029import com.android.documentsui.Model;
Steve McKay990f76e2016-09-16 12:36:58 -070030import com.android.documentsui.base.EventListener;
Steve McKayd9caa6a2016-09-15 16:36:45 -070031import com.android.documentsui.base.State;
Garfield Tane9670332017-03-06 18:33:23 -080032import com.android.documentsui.Model.Update;
Steve McKayc5ecf892015-12-22 18:15:31 -080033
34import java.util.ArrayList;
Steve McKayc5ecf892015-12-22 18:15:31 -080035import java.util.List;
Steve McKayc5ecf892015-12-22 18:15:31 -080036
37/**
38 * Adapts from dirlist.Model to something RecyclerView understands.
39 */
40final class ModelBackedDocumentsAdapter extends DocumentsAdapter {
41
Ben Kwaf4b0ff62016-02-02 12:11:10 -080042 private static final String TAG = "ModelBackedDocuments";
Steve McKayc5ecf892015-12-22 18:15:31 -080043
44 // Provides access to information needed when creating and view holders. This
45 // isn't an ideal pattern (more transitive dependency stuff) but good enough for now.
46 private final Environment mEnv;
47 private final IconHelper mIconHelper; // a transitive dependency of the holders.
48
49 /**
50 * An ordered list of model IDs. This is the data structure that determines what shows up in
51 * the UI, and where.
52 */
53 private List<String> mModelIds = new ArrayList<>();
Steve McKay990f76e2016-09-16 12:36:58 -070054 private EventListener<Model.Update> mModelUpdateListener;
Steve McKayc5ecf892015-12-22 18:15:31 -080055
Steve McKayc5ecf892015-12-22 18:15:31 -080056 public ModelBackedDocumentsAdapter(Environment env, IconHelper iconHelper) {
57 mEnv = env;
58 mIconHelper = iconHelper;
Steve McKay990f76e2016-09-16 12:36:58 -070059
60 mModelUpdateListener = new EventListener<Model.Update>() {
61 @Override
62 public void accept(Update event) {
Ben Linf8f06e92017-01-27 17:15:48 -080063 if (event.hasException()) {
64 onModelUpdateFailed(event.getException());
Steve McKay990f76e2016-09-16 12:36:58 -070065 } else {
66 onModelUpdate(mEnv.getModel());
67 }
68 }
69 };
70 }
71
72 @Override
73 EventListener<Update> getModelUpdateListener() {
74 return mModelUpdateListener;
Steve McKayc5ecf892015-12-22 18:15:31 -080075 }
76
77 @Override
78 public DocumentHolder onCreateViewHolder(ViewGroup parent, int viewType) {
79 DocumentHolder holder = null;
80 final State state = mEnv.getDisplayState();
81 switch (state.derivedMode) {
82 case MODE_GRID:
83 switch (viewType) {
84 case ITEM_TYPE_DIRECTORY:
85 holder = new GridDirectoryHolder(mEnv.getContext(), parent);
86 break;
87 case ITEM_TYPE_DOCUMENT:
88 holder = new GridDocumentHolder(mEnv.getContext(), parent, mIconHelper);
89 break;
90 default:
91 throw new IllegalStateException("Unsupported layout type.");
92 }
93 break;
94 case MODE_LIST:
95 holder = new ListDocumentHolder(mEnv.getContext(), parent, mIconHelper);
96 break;
Steve McKayc5ecf892015-12-22 18:15:31 -080097 default:
98 throw new IllegalStateException("Unsupported layout mode.");
99 }
100
101 mEnv.initDocumentHolder(holder);
102 return holder;
103 }
104
105 @Override
106 public void onBindViewHolder(DocumentHolder holder, int position, List<Object> payload) {
107 if (payload.contains(SELECTION_CHANGED_MARKER)) {
108 final boolean selected = mEnv.isSelected(mModelIds.get(position));
Ben Kwa4c2f1a62016-03-16 12:13:21 -0700109 holder.setSelected(selected, true);
Steve McKayc5ecf892015-12-22 18:15:31 -0800110 } else {
111 onBindViewHolder(holder, position);
112 }
113 }
114
115 @Override
116 public void onBindViewHolder(DocumentHolder holder, int position) {
117 String modelId = mModelIds.get(position);
118 Cursor cursor = mEnv.getModel().getItem(modelId);
Steve McKay358c3ec2016-10-21 09:16:57 -0700119 holder.bind(cursor, modelId);
Steve McKayc5ecf892015-12-22 18:15:31 -0800120
121 final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
122 final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
123
Steve McKay2e744402016-03-08 11:37:22 -0800124 boolean enabled = mEnv.isDocumentEnabled(docMimeType, docFlags);
125 boolean selected = mEnv.isSelected(modelId);
126 if (!enabled) {
127 assert(!selected);
128 }
129 holder.setEnabled(enabled);
Ben Kwa4c2f1a62016-03-16 12:13:21 -0700130 holder.setSelected(mEnv.isSelected(modelId), false);
Steve McKayc5ecf892015-12-22 18:15:31 -0800131
132 mEnv.onBindDocumentHolder(holder, cursor);
133 }
134
135 @Override
136 public int getItemCount() {
137 return mModelIds.size();
138 }
139
Steve McKay990f76e2016-09-16 12:36:58 -0700140 private void onModelUpdate(Model model) {
Tomasz Mikolajewskif27c2742016-03-07 18:01:45 +0900141 String[] modelIds = model.getModelIds();
142 mModelIds = new ArrayList<>(modelIds.length);
Steve McKayc5ecf892015-12-22 18:15:31 -0800143 for (String id : modelIds) {
Ben Lin7b38f342016-12-14 11:52:35 -0800144 mModelIds.add(id);
Steve McKayc5ecf892015-12-22 18:15:31 -0800145 }
Steve McKayc5ecf892015-12-22 18:15:31 -0800146 }
147
Steve McKay990f76e2016-09-16 12:36:58 -0700148 private void onModelUpdateFailed(Exception e) {
Steve McKayc5ecf892015-12-22 18:15:31 -0800149 Log.w(TAG, "Model update failed.", e);
150 mModelIds.clear();
151 }
152
153 @Override
154 public String getModelId(int adapterPosition) {
155 return mModelIds.get(adapterPosition);
156 }
157
158 @Override
Steve McKayc5ecf892015-12-22 18:15:31 -0800159 public List<String> getModelIds() {
160 return mModelIds;
161 }
162
163 @Override
164 public int getItemViewType(int position) {
165 return isDirectory(mEnv.getModel(), position)
166 ? ITEM_TYPE_DIRECTORY
167 : ITEM_TYPE_DOCUMENT;
168 }
169
Steve McKay4f78ba62016-10-04 16:48:49 -0700170 /**
171 * @return true if the item type is either document or directory, false for all other
172 * possible types.
173 */
174 public static boolean isContentType(int type) {
175 switch (type) {
176 case ModelBackedDocumentsAdapter.ITEM_TYPE_DOCUMENT:
177 case ModelBackedDocumentsAdapter.ITEM_TYPE_DIRECTORY:
178 return true;
179 }
180 return false;
181 }
182
Steve McKayc5ecf892015-12-22 18:15:31 -0800183 @Override
Steve McKaye9104032016-01-05 12:53:35 -0800184 public void onItemSelectionChanged(String id) {
Steve McKayc5ecf892015-12-22 18:15:31 -0800185 int position = mModelIds.indexOf(id);
186
187 if (position >= 0) {
188 notifyItemChanged(position, SELECTION_CHANGED_MARKER);
189 } else {
190 Log.w(TAG, "Item change notification received for unknown item: " + id);
191 }
192 }
193}