QuickViewIntentBuilder.java revision 1eafb666c24736be4454c199a62c256c55e86bc4
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.DocumentContext;
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 DocumentContext mContext;
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            DocumentContext context) {
59
60        mPkgManager = pkgManager;
61        mResources = resources;
62        mDocument = doc;
63        mContext = context;
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        Intent intent = new Intent(Intent.ACTION_QUICK_VIEW);
76        intent.setDataAndType(mDocument.derivedUri, mDocument.mimeType);
77        intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
78
79        if (TextUtils.isEmpty(trustedPkg)) {
80            if (hasRegisteredHandler(intent)) {
81                return intent;
82            }
83        } else {
84            intent.setPackage(trustedPkg);
85            if (hasRegisteredHandler(intent)) {
86                // We have a trusted handler. Load all of the docs into the intent.
87                Cursor cursor = mContext.getCursor();
88                for (int i = 0; i < cursor.getCount(); i++) {
89                    onNextItem(i, cursor);
90                }
91                intent.putExtra(Intent.EXTRA_INDEX, mDocumentLocation);
92                intent.setClipData(mClipData);
93
94                return intent;
95            } else {
96                Log.e(TAG, "Can't resolve trusted quick view package: " + trustedPkg);
97            }
98        }
99
100        return null;
101    }
102
103    private boolean hasRegisteredHandler(Intent intent) {
104        // Try to resolve the intent. If a matching app isn't installed, it won't resolve.
105        return intent.resolveActivity(mPkgManager) != null;
106    }
107
108    private void onNextItem(int index, Cursor cursor) {
109        cursor.moveToPosition(index);
110
111        String mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
112        if (Document.MIME_TYPE_DIR.equals(mimeType)) {
113            return;
114        }
115
116        String id = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
117        String authority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY);
118        Uri uri = DocumentsContract.buildDocumentUri(authority, id);
119        if (DEBUG) Log.d(TAG, "Including file[" + id + "] @ " + uri);
120
121        if (id.equals(mDocument.documentId)) {
122            if (DEBUG) Log.d(TAG, "Found starting point for QV. " + index);
123            mDocumentLocation = index;
124        }
125
126        ClipData.Item item = new ClipData.Item(uri);
127        if (mClipData == null) {
128            mClipData = new ClipData(
129                    "URIs", new String[]{ClipDescription.MIMETYPE_TEXT_URILIST}, item);
130        } else {
131            mClipData.addItem(item);
132        }
133    }
134}
135