QuickViewIntentBuilder.java revision c2b1237ca53fe2de68bdd9e59c1dd3572679965d
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
17package com.android.documentsui;
18
19import static com.android.documentsui.Shared.DEBUG;
20import static com.android.documentsui.Shared.TAG;
21import static com.android.documentsui.model.DocumentInfo.getCursorString;
22
23import android.content.ClipData;
24import android.content.ClipDescription;
25import android.content.ComponentName;
26import android.content.Intent;
27import android.content.pm.PackageManager;
28import android.content.res.Resources;
29import android.database.Cursor;
30import android.net.Uri;
31import android.provider.DocumentsContract;
32import android.provider.DocumentsContract.Document;
33import android.support.annotation.Nullable;
34import android.text.TextUtils;
35import android.util.Log;
36
37import com.android.documentsui.BaseActivity.SiblingProvider;
38import com.android.documentsui.model.DocumentInfo;
39
40/**
41 * Provides support for gather a list of quick-viewable files into a quick view intent.
42 */
43final class QuickViewIntentBuilder {
44
45    private final DocumentInfo mDocument;
46    private final SiblingProvider mSiblings;
47
48    private final PackageManager mPkgManager;
49    private final Resources mResources;
50
51    private ClipData mClipData;
52    private int mDocumentLocation;
53
54    public QuickViewIntentBuilder(
55            PackageManager pkgManager,
56            Resources resources,
57            DocumentInfo doc,
58            SiblingProvider siblings) {
59
60        mPkgManager = pkgManager;
61        mResources = resources;
62        mDocument = doc;
63        mSiblings = siblings;
64    }
65
66    /**
67     * Builds the intent for quick viewing. Short circuits building if a handler cannot
68     * be resolved; in this case {@code null} is returned.
69     */
70    @Nullable Intent build() {
71        if (DEBUG) Log.d(TAG, "Preparing intent for doc:" + mDocument.documentId);
72
73        String trustedPkg = mResources.getString(R.string.trusted_quick_viewer_package);
74
75        if (!TextUtils.isEmpty(trustedPkg)) {
76            Intent intent = new Intent(Intent.ACTION_QUICK_VIEW);
77            intent.setDataAndType(mDocument.derivedUri, mDocument.mimeType);
78            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
79            intent.setPackage(trustedPkg);
80            if (hasRegisteredHandler(intent)) {
81                Cursor cursor = mSiblings.getCursor();
82                for (int i = 0; i < cursor.getCount(); i++) {
83                    onNextItem(i, cursor);
84                }
85                intent.putExtra(Intent.EXTRA_INDEX, mDocumentLocation);
86                intent.setClipData(mClipData);
87
88                return intent;
89            } else {
90                Log.e(TAG, "Can't resolve trusted quick view package: " + trustedPkg);
91            }
92        }
93
94        return null;
95    }
96
97    private boolean hasRegisteredHandler(Intent intent) {
98        // Try to resolve the intent. If a matching app isn't installed, it won't resolve.
99        return intent.resolveActivity(mPkgManager) != null;
100    }
101
102    private void onNextItem(int index, Cursor cursor) {
103        cursor.moveToPosition(index);
104
105        String mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
106        if (Document.MIME_TYPE_DIR.equals(mimeType)) {
107            return;
108        }
109
110        String id = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
111        String authority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY);
112        Uri uri = DocumentsContract.buildDocumentUri(authority, id);
113        if (DEBUG) Log.d(TAG, "Including file[" + id + "] @ " + uri);
114
115        if (id.equals(mDocument.documentId)) {
116            if (DEBUG) Log.d(TAG, "Found starting point for QV. " + index);
117            mDocumentLocation = index;
118        }
119
120        ClipData.Item item = new ClipData.Item(uri);
121        if (mClipData == null) {
122            mClipData = new ClipData(
123                    "URIs", new String[]{ClipDescription.MIMETYPE_TEXT_URILIST}, item);
124        } else {
125            mClipData.addItem(item);
126        }
127    }
128}
129