184bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan/*
284bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan * Copyright (C) 2016 The Android Open Source Project
384bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan *
484bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan * Licensed under the Apache License, Version 2.0 (the "License");
584bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan * you may not use this file except in compliance with the License.
684bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan * You may obtain a copy of the License at
784bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan *
884bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan *      http://www.apache.org/licenses/LICENSE-2.0
984bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan *
1084bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan * Unless required by applicable law or agreed to in writing, software
1184bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan * distributed under the License is distributed on an "AS IS" BASIS,
1284bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1384bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan * See the License for the specific language governing permissions and
1484bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan * limitations under the License.
1584bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan */
1684bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan
174f78ba643270b9d84da1952d8e408220b25ec6fdSteve McKaypackage com.android.documentsui.selection;
1884bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan
19d080506e3aa8547605cd4783eb660775d7d2b8eeSteve McKayimport static com.android.documentsui.base.DocumentInfo.getCursorInt;
20d080506e3aa8547605cd4783eb660775d7d2b8eeSteve McKayimport static com.android.documentsui.base.DocumentInfo.getCursorString;
2184bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan
22253a99248f1f3d50cd357d902bfc52e7b9367446Jon Mannimport android.content.Context;
23253a99248f1f3d50cd357d902bfc52e7b9367446Jon Mannimport android.content.pm.PackageManager;
24253a99248f1f3d50cd357d902bfc52e7b9367446Jon Mannimport android.content.pm.ProviderInfo;
2584bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tanimport android.database.Cursor;
2684bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tanimport android.provider.DocumentsContract.Document;
2784bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tanimport android.util.Log;
2884bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan
2984bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tanimport com.android.documentsui.MenuManager;
305a8e378a4b550d8a8e31d3bcc93ec3bf485d7c16Tomasz Mikolajewskiimport com.android.documentsui.archives.ArchivesProvider;
31d071895ec72bbb9414f6672ff808ec42b8e2d850Steve McKayimport com.android.documentsui.base.MimeTypes;
325a8e378a4b550d8a8e31d3bcc93ec3bf485d7c16Tomasz Mikolajewskiimport com.android.documentsui.roots.RootCursorWrapper;
3384bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan
3484bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tanimport java.util.function.Function;
3584bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan
3684bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan/**
3784bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan * A class that holds metadata
3884bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan */
394f78ba643270b9d84da1952d8e408220b25ec6fdSteve McKaypublic class SelectionMetadata
404f78ba643270b9d84da1952d8e408220b25ec6fdSteve McKay        implements MenuManager.SelectionDetails, SelectionManager.ItemCallback {
4184bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan
4284bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    private static final String TAG = "SelectionMetadata";
437f7ee10edaac1214e23f267a595014b510562d1eBen Lin    private final static int FLAG_CAN_DELETE =
447f7ee10edaac1214e23f267a595014b510562d1eBen Lin            Document.FLAG_SUPPORTS_REMOVE | Document.FLAG_SUPPORTS_DELETE;
4584bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan
4684bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    private final Function<String, Cursor> mDocFinder;
4784bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan
4806c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan    private int mDirectoryCount = 0;
4906c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan    private int mFileCount = 0;
5006c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan
5184bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    // Partial files are files that haven't been fully downloaded.
5284bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    private int mPartialCount = 0;
5384bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    private int mWritableDirectoryCount = 0;
5484bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    private int mNoDeleteCount = 0;
5584bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    private int mNoRenameCount = 0;
565a8e378a4b550d8a8e31d3bcc93ec3bf485d7c16Tomasz Mikolajewski    private int mInArchiveCount = 0;
57253a99248f1f3d50cd357d902bfc52e7b9367446Jon Mann    private boolean mSupportsSettings = false;
5884bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan
594f78ba643270b9d84da1952d8e408220b25ec6fdSteve McKay    public SelectionMetadata(Function<String, Cursor> docFinder) {
6084bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan        mDocFinder = docFinder;
6184bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    }
6284bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan
6384bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    @Override
6484bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    public void onItemStateChanged(String modelId, boolean selected) {
6584bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan        final Cursor cursor = mDocFinder.apply(modelId);
6684bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan        if (cursor == null) {
6784bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan            Log.w(TAG, "Model returned null cursor for document: " + modelId
6884bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan                    + ". Ignoring state changed event.");
6984bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan            return;
7084bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan        }
7184bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan
7206c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan        final int delta = selected ? 1 : -1;
7306c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan
7484bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan        final String mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
75d071895ec72bbb9414f6672ff808ec42b8e2d850Steve McKay        if (MimeTypes.isDirectoryType(mimeType)) {
7606c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan            mDirectoryCount += delta;
7706c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan        } else {
7806c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan            mFileCount += delta;
7984bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan        }
8084bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan
8184bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan        final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
8284bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan        if ((docFlags & Document.FLAG_PARTIAL) != 0) {
8306c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan            mPartialCount += delta;
8484bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan        }
8584bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan        if ((docFlags & Document.FLAG_DIR_SUPPORTS_CREATE) != 0) {
8606c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan            mWritableDirectoryCount += delta;
8784bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan        }
887f7ee10edaac1214e23f267a595014b510562d1eBen Lin        if ((docFlags & FLAG_CAN_DELETE) == 0) {
8906c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan            mNoDeleteCount += delta;
9084bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan        }
9184bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan        if ((docFlags & Document.FLAG_SUPPORTS_RENAME) == 0) {
9206c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan            mNoRenameCount += delta;
9384bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan        }
945a8e378a4b550d8a8e31d3bcc93ec3bf485d7c16Tomasz Mikolajewski        if ((docFlags & Document.FLAG_PARTIAL) != 0) {
955a8e378a4b550d8a8e31d3bcc93ec3bf485d7c16Tomasz Mikolajewski            mPartialCount += delta;
965a8e378a4b550d8a8e31d3bcc93ec3bf485d7c16Tomasz Mikolajewski        }
97253a99248f1f3d50cd357d902bfc52e7b9367446Jon Mann        mSupportsSettings = (docFlags & Document.FLAG_SUPPORTS_SETTINGS) != 0 &&
98253a99248f1f3d50cd357d902bfc52e7b9367446Jon Mann                (mFileCount + mDirectoryCount) == 1;
99253a99248f1f3d50cd357d902bfc52e7b9367446Jon Mann
1005a8e378a4b550d8a8e31d3bcc93ec3bf485d7c16Tomasz Mikolajewski
1015a8e378a4b550d8a8e31d3bcc93ec3bf485d7c16Tomasz Mikolajewski        final String authority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY);
1025a8e378a4b550d8a8e31d3bcc93ec3bf485d7c16Tomasz Mikolajewski        if (ArchivesProvider.AUTHORITY.equals(authority)) {
1035a8e378a4b550d8a8e31d3bcc93ec3bf485d7c16Tomasz Mikolajewski            mInArchiveCount += delta;
1045a8e378a4b550d8a8e31d3bcc93ec3bf485d7c16Tomasz Mikolajewski        }
10584bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    }
10684bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan
10784bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    @Override
108b8874fd0df55113d472c6704b91bd493c577caebGarfield Tan    public void onSelectionReset() {
109b8874fd0df55113d472c6704b91bd493c577caebGarfield Tan        mFileCount = 0;
110b8874fd0df55113d472c6704b91bd493c577caebGarfield Tan        mDirectoryCount = 0;
111b8874fd0df55113d472c6704b91bd493c577caebGarfield Tan        mPartialCount = 0;
112b8874fd0df55113d472c6704b91bd493c577caebGarfield Tan        mWritableDirectoryCount = 0;
113b8874fd0df55113d472c6704b91bd493c577caebGarfield Tan        mNoDeleteCount = 0;
114b8874fd0df55113d472c6704b91bd493c577caebGarfield Tan        mNoRenameCount = 0;
115b8874fd0df55113d472c6704b91bd493c577caebGarfield Tan    }
116b8874fd0df55113d472c6704b91bd493c577caebGarfield Tan
117b8874fd0df55113d472c6704b91bd493c577caebGarfield Tan    @Override
11884bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    public boolean containsDirectories() {
11984bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan        return mDirectoryCount > 0;
12084bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    }
12184bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan
12284bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    @Override
12306c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan    public boolean containsFiles() {
12406c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan        return mFileCount > 0;
12506c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan    }
12606c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan
12706c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan    @Override
12806c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan    public int size() {
12906c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan        return mDirectoryCount + mFileCount;
13006c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan    }
13106c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan
13206c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan    @Override
13384bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    public boolean containsPartialFiles() {
13484bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan        return mPartialCount > 0;
13584bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    }
13684bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan
13784bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    @Override
1387f7ee10edaac1214e23f267a595014b510562d1eBen Lin    public boolean containsFilesInArchive() {
1397f7ee10edaac1214e23f267a595014b510562d1eBen Lin        return mInArchiveCount > 0;
1407f7ee10edaac1214e23f267a595014b510562d1eBen Lin    }
1417f7ee10edaac1214e23f267a595014b510562d1eBen Lin
1427f7ee10edaac1214e23f267a595014b510562d1eBen Lin    @Override
14384bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    public boolean canDelete() {
14406c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan        return size() > 0 && mNoDeleteCount == 0;
14584bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    }
14684bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan
14784bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    @Override
1485a8e378a4b550d8a8e31d3bcc93ec3bf485d7c16Tomasz Mikolajewski    public boolean canExtract() {
1495a8e378a4b550d8a8e31d3bcc93ec3bf485d7c16Tomasz Mikolajewski        return size() > 0 && mInArchiveCount == size();
1505a8e378a4b550d8a8e31d3bcc93ec3bf485d7c16Tomasz Mikolajewski    }
1515a8e378a4b550d8a8e31d3bcc93ec3bf485d7c16Tomasz Mikolajewski
1525a8e378a4b550d8a8e31d3bcc93ec3bf485d7c16Tomasz Mikolajewski    @Override
15384bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    public boolean canRename() {
15406c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan        return mNoRenameCount == 0 && size() == 1;
15584bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    }
15684bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan
15784bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    @Override
158253a99248f1f3d50cd357d902bfc52e7b9367446Jon Mann    public boolean canViewInOwner() {
159253a99248f1f3d50cd357d902bfc52e7b9367446Jon Mann        return mSupportsSettings;
160253a99248f1f3d50cd357d902bfc52e7b9367446Jon Mann    }
161253a99248f1f3d50cd357d902bfc52e7b9367446Jon Mann
162253a99248f1f3d50cd357d902bfc52e7b9367446Jon Mann    @Override
16384bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    public boolean canPasteInto() {
16406c4b1111ec49bb70ec6977e86322f1c8f9bbe58Garfield Tan        return mDirectoryCount == 1 && mWritableDirectoryCount == 1 && size() == 1;
16584bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan    }
166ac3e63e584a079c9efd84de66e65a8f6c05b773dTomasz Mikolajewski
167ac3e63e584a079c9efd84de66e65a8f6c05b773dTomasz Mikolajewski    @Override
168ac3e63e584a079c9efd84de66e65a8f6c05b773dTomasz Mikolajewski    public boolean canOpenWith() {
1698c9b9fba64a063ab04f0ff91ab9cfe8ee8348c60Tomasz Mikolajewski        return size() == 1 && mDirectoryCount == 0 && mInArchiveCount == 0 && mPartialCount == 0;
170ac3e63e584a079c9efd84de66e65a8f6c05b773dTomasz Mikolajewski    }
17184bd0f13bd02ea26acc937b00c050884dc7546efGarfield Tan}
172