1 /* 2 * Copyright (C) 2017 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 package com.android.documentsui.dirlist; 17 18 import static android.support.v4.util.Preconditions.checkArgument; 19 import static com.android.documentsui.base.DocumentInfo.getCursorInt; 20 import static com.android.documentsui.base.DocumentInfo.getCursorString; 21 22 import android.database.Cursor; 23 import android.provider.DocumentsContract.Document; 24 import android.support.v7.widget.RecyclerView; 25 import android.util.Log; 26 27 import com.android.documentsui.ActivityConfig; 28 import com.android.documentsui.Model; 29 import com.android.documentsui.base.State; 30 import com.android.documentsui.selection.SelectionHelper.SelectionPredicate; 31 32 /** 33 * Class embodying the logic as to whether an item (specified by id or position) 34 * can be selected (or not). 35 */ 36 final class DocsSelectionPredicate extends SelectionPredicate { 37 38 private ActivityConfig mConfig; 39 private Model mModel; 40 private RecyclerView mRecView; 41 private State mState; 42 43 DocsSelectionPredicate( 44 ActivityConfig config, State state, Model model, RecyclerView recView) { 45 46 checkArgument(config != null); 47 checkArgument(state != null); 48 checkArgument(model != null); 49 checkArgument(recView != null); 50 51 mConfig = config; 52 mState = state; 53 mModel = model; 54 mRecView = recView; 55 56 } 57 58 @Override 59 public boolean canSetStateForId(String id, boolean nextState) { 60 if (nextState) { 61 // Check if an item can be selected 62 final Cursor cursor = mModel.getItem(id); 63 if (cursor == null) { 64 Log.w(DirectoryFragment.TAG, "Couldn't obtain cursor for id: " + id); 65 return false; 66 } 67 68 final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); 69 final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS); 70 return mConfig.canSelectType(docMimeType, docFlags, mState); 71 } 72 73 // Right now all selected items can be deselected. 74 return true; 75 } 76 77 @Override 78 public boolean canSetStateAtPosition(int position, boolean nextState) { 79 // This method features a nextState arg for symmetry. 80 // But, there are no current uses for checking un-selecting state by position. 81 // So rather than have some unsuspecting client think canSetState(int, false) 82 // will ever do anything. Let's just be grumpy about it. 83 assert nextState == true; 84 85 // NOTE: Given that we have logic in some places disallowing selection, 86 // it may be a bug that Band and Gesture based selections don't 87 // also verify something can be unselected. 88 89 // The band selection model only operates on documents and directories. 90 // Exclude other types of adapter items like whitespace and dividers. 91 RecyclerView.ViewHolder vh = mRecView.findViewHolderForAdapterPosition(position); 92 return ModelBackedDocumentsAdapter.isContentType(vh.getItemViewType()); 93 } 94 95 @Override 96 public boolean canSelectMultiple() { 97 return mState.allowMultiple; 98 } 99 } 100