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 */
16package com.android.documentsui.base;
17
18import static com.android.documentsui.base.DocumentInfo.getCursorInt;
19import static com.android.documentsui.base.DocumentInfo.getCursorString;
20
21import android.database.Cursor;
22import android.provider.DocumentsContract.Document;
23
24import com.android.documentsui.archives.ArchivesProvider;
25import com.android.documentsui.roots.RootCursorWrapper;
26
27import java.util.function.Predicate;
28
29/**
30 * Predicates for matching certain types of document records
31 * in {@link Cursor}s.
32 */
33public final class DocumentFilters {
34
35    private static int MOVABLE_MASK = Document.FLAG_SUPPORTS_REMOVE
36            | Document.FLAG_SUPPORTS_DELETE
37            | Document.FLAG_SUPPORTS_MOVE;
38
39    public static final Predicate<Cursor> ANY = (Cursor c) -> { return true; };
40    public static final Predicate<Cursor> VIRTUAL  = DocumentFilters::isVirtual;
41    public static final Predicate<Cursor> NOT_MOVABLE = DocumentFilters::isNotMovable;
42    private static final Predicate<Cursor> O_SHARABLE = DocumentFilters::isSharableInO;
43    private static final Predicate<Cursor> PREO_SHARABLE = DocumentFilters::isSharablePreO;
44
45    public static Predicate<Cursor> sharable(Features features) {
46        return features.isVirtualFilesSharingEnabled()
47                ? DocumentFilters.O_SHARABLE
48                : DocumentFilters.PREO_SHARABLE;
49    }
50
51    private static boolean isSharableInO(Cursor c) {
52        int flags = getCursorInt(c, Document.COLUMN_FLAGS);
53        String authority = getCursorString(c, RootCursorWrapper.COLUMN_AUTHORITY);
54
55        return (flags & Document.FLAG_PARTIAL) == 0
56                && !ArchivesProvider.AUTHORITY.equals(authority);
57    }
58
59    /**
60     * Filter that passes (returns true) for all files which can be shared in O.
61     */
62    private static boolean isSharablePreO(Cursor c) {
63        int flags = getCursorInt(c, Document.COLUMN_FLAGS);
64        String authority = getCursorString(c, RootCursorWrapper.COLUMN_AUTHORITY);
65
66        return (flags & Document.FLAG_PARTIAL) == 0
67                && (flags & Document.FLAG_VIRTUAL_DOCUMENT) == 0
68                && !ArchivesProvider.AUTHORITY.equals(authority);
69    }
70
71    /**
72     * Filter that passes (returns true) only virtual documents.
73     */
74    private static final boolean isVirtual(Cursor c) {
75        int flags = getCursorInt(c, Document.COLUMN_FLAGS);
76        return (flags & Document.FLAG_VIRTUAL_DOCUMENT) != 0;
77    }
78
79    /**
80     * Filter that passes (returns true) for files that can not be moved.
81     */
82    private static final boolean isNotMovable(Cursor c) {
83        int flags = getCursorInt(c, Document.COLUMN_FLAGS);
84        return (flags & MOVABLE_MASK) == 0;
85    }
86}
87