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 17 package com.android.documentsui; 18 19 import android.support.annotation.VisibleForTesting; 20 import android.support.v7.widget.RecyclerView; 21 22 import com.android.documentsui.selection.DefaultSelectionHelper; 23 import com.android.documentsui.selection.DefaultSelectionHelper.SelectionMode; 24 import com.android.documentsui.selection.MutableSelection; 25 import com.android.documentsui.selection.Selection; 26 import com.android.documentsui.selection.SelectionHelper; 27 28 import java.util.Set; 29 30 import javax.annotation.Nullable; 31 32 /** 33 * DocumentsUI SelectManager implementation that creates delegate instances 34 * each time reset is called. 35 */ 36 public final class DocsSelectionHelper extends SelectionHelper { 37 38 private final DelegateFactory mFactory; 39 private final @SelectionMode int mSelectionMode; 40 41 // initialize to a dummy object incase we get some input 42 // event drive calls before we're properly initialized. 43 // See: b/69306667. 44 private SelectionHelper mDelegate = new DummySelectionHelper(); 45 46 @VisibleForTesting DocsSelectionHelper(DelegateFactory factory, @SelectionMode int mode)47 DocsSelectionHelper(DelegateFactory factory, @SelectionMode int mode) { 48 mFactory = factory; 49 mSelectionMode = mode; 50 } 51 reset( RecyclerView.Adapter<?> adapter, StableIdProvider stableIds, SelectionPredicate canSetState)52 public SelectionHelper reset( 53 RecyclerView.Adapter<?> adapter, 54 StableIdProvider stableIds, 55 SelectionPredicate canSetState) { 56 57 if (mDelegate != null) { 58 mDelegate.clearSelection(); 59 } 60 61 mDelegate = mFactory.create(mSelectionMode, adapter, stableIds, canSetState); 62 return this; 63 } 64 65 @Override addObserver(SelectionObserver listener)66 public void addObserver(SelectionObserver listener) { 67 mDelegate.addObserver(listener); 68 } 69 70 @Override hasSelection()71 public boolean hasSelection() { 72 return mDelegate.hasSelection(); 73 } 74 75 @Override getSelection()76 public Selection getSelection() { 77 return mDelegate.getSelection(); 78 } 79 80 @Override copySelection(Selection dest)81 public void copySelection(Selection dest) { 82 mDelegate.copySelection(dest); 83 } 84 85 @Override isSelected(String id)86 public boolean isSelected(String id) { 87 return mDelegate.isSelected(id); 88 } 89 90 @VisibleForTesting replaceSelection(Iterable<String> ids)91 public void replaceSelection(Iterable<String> ids) { 92 mDelegate.clearSelection(); 93 mDelegate.setItemsSelected(ids, true); 94 } 95 96 @Override restoreSelection(Selection other)97 public void restoreSelection(Selection other) { 98 mDelegate.restoreSelection(other); 99 } 100 101 @Override setItemsSelected(Iterable<String> ids, boolean selected)102 public boolean setItemsSelected(Iterable<String> ids, boolean selected) { 103 return mDelegate.setItemsSelected(ids, selected); 104 } 105 106 @Override clearSelection()107 public void clearSelection() { 108 mDelegate.clearSelection(); 109 } 110 111 @Override select(String modelId)112 public boolean select(String modelId) { 113 return mDelegate.select(modelId); 114 } 115 116 @Override deselect(String modelId)117 public boolean deselect(String modelId) { 118 return mDelegate.deselect(modelId); 119 } 120 121 @Override startRange(int pos)122 public void startRange(int pos) { 123 mDelegate.startRange(pos); 124 } 125 126 @Override extendRange(int pos)127 public void extendRange(int pos) { 128 mDelegate.extendRange(pos); 129 } 130 131 @Override extendProvisionalRange(int pos)132 public void extendProvisionalRange(int pos) { 133 mDelegate.extendProvisionalRange(pos); 134 } 135 136 @Override clearProvisionalSelection()137 public void clearProvisionalSelection() { 138 mDelegate.clearProvisionalSelection(); 139 } 140 141 @Override setProvisionalSelection(Set<String> newSelection)142 public void setProvisionalSelection(Set<String> newSelection) { 143 mDelegate.setProvisionalSelection(newSelection); 144 } 145 146 @Override mergeProvisionalSelection()147 public void mergeProvisionalSelection() { 148 mDelegate.mergeProvisionalSelection(); 149 } 150 151 @Override endRange()152 public void endRange() { 153 mDelegate.endRange(); 154 } 155 156 @Override isRangeActive()157 public boolean isRangeActive() { 158 return mDelegate.isRangeActive(); 159 } 160 161 @Override anchorRange(int position)162 public void anchorRange(int position) { 163 mDelegate.anchorRange(position); 164 } 165 createMultiSelect()166 public static DocsSelectionHelper createMultiSelect() { 167 return new DocsSelectionHelper( 168 DelegateFactory.INSTANCE, 169 DefaultSelectionHelper.MODE_MULTIPLE); 170 } 171 createSingleSelect()172 public static DocsSelectionHelper createSingleSelect() { 173 return new DocsSelectionHelper( 174 DelegateFactory.INSTANCE, 175 DefaultSelectionHelper.MODE_SINGLE); 176 } 177 178 /** 179 * Use of a factory to create selection manager instances allows testable instances to 180 * be inject from tests. 181 */ 182 @VisibleForTesting 183 static class DelegateFactory { 184 static final DelegateFactory INSTANCE = new DelegateFactory(); 185 create( @electionMode int mode, RecyclerView.Adapter<?> adapter, StableIdProvider stableIds, SelectionPredicate canSetState)186 SelectionHelper create( 187 @SelectionMode int mode, 188 RecyclerView.Adapter<?> adapter, 189 StableIdProvider stableIds, 190 SelectionPredicate canSetState) { 191 192 return new DefaultSelectionHelper(mode, adapter, stableIds, canSetState); 193 } 194 } 195 196 /** 197 * A dummy SelectHelper used by DocsSelectionHelper before a real 198 * SelectionHelper has been initialized by DirectoryFragment. 199 */ 200 private static final class DummySelectionHelper extends SelectionHelper { 201 202 @Override addObserver(SelectionObserver listener)203 public void addObserver(SelectionObserver listener) { 204 } 205 206 @Override hasSelection()207 public boolean hasSelection() { 208 return false; 209 } 210 211 @Override getSelection()212 public Selection getSelection() { 213 return new MutableSelection(); 214 } 215 216 @Override copySelection(Selection dest)217 public void copySelection(Selection dest) { 218 } 219 220 @Override isSelected(String id)221 public boolean isSelected(String id) { 222 return false; 223 } 224 225 @VisibleForTesting replaceSelection(Iterable<String> ids)226 public void replaceSelection(Iterable<String> ids) { 227 } 228 229 @Override restoreSelection(Selection other)230 public void restoreSelection(Selection other) { 231 } 232 233 @Override setItemsSelected(Iterable<String> ids, boolean selected)234 public boolean setItemsSelected(Iterable<String> ids, boolean selected) { 235 return false; 236 } 237 238 @Override clearSelection()239 public void clearSelection() { 240 } 241 242 @Override select(String modelId)243 public boolean select(String modelId) { 244 return false; 245 } 246 247 @Override deselect(String modelId)248 public boolean deselect(String modelId) { 249 return false; 250 } 251 252 @Override startRange(int pos)253 public void startRange(int pos) { 254 } 255 256 @Override extendRange(int pos)257 public void extendRange(int pos) { 258 } 259 260 @Override extendProvisionalRange(int pos)261 public void extendProvisionalRange(int pos) { 262 } 263 264 @Override clearProvisionalSelection()265 public void clearProvisionalSelection() { 266 } 267 268 @Override setProvisionalSelection(Set<String> newSelection)269 public void setProvisionalSelection(Set<String> newSelection) { 270 } 271 272 @Override mergeProvisionalSelection()273 public void mergeProvisionalSelection() { 274 } 275 276 @Override endRange()277 public void endRange() { 278 } 279 280 @Override isRangeActive()281 public boolean isRangeActive() { 282 return false; 283 } 284 285 @Override anchorRange(int position)286 public void anchorRange(int position) { 287 } 288 } 289 } 290