QuickViewIntentBuilder.java revision 3d988a969f39ca34ef89c449a0675164499c9a3a
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.dirlist.Model;
38import com.android.documentsui.model.DocumentInfo;
39
40import java.util.List;
41
42/**
43 * Provides support for gather a list of quick-viewable files into a quick view intent.
44 */
45final class QuickViewIntentBuilder {
46
47    private final DocumentInfo mDocument;
48    private final Model mModel;
49
50    private final PackageManager mPkgManager;
51    private final Resources mResources;
52
53    private ClipData mClipData;
54    private int mDocumentLocation;
55
56    public QuickViewIntentBuilder(
57            PackageManager pkgManager,
58            Resources resources,
59            DocumentInfo doc,
60            Model model) {
61
62        mPkgManager = pkgManager;
63        mResources = resources;
64        mDocument = doc;
65        mModel = model;
66    }
67
68    /**
69     * Builds the intent for quick viewing. Short circuits building if a handler cannot
70     * be resolved; in this case {@code null} is returned.
71     */
72    @Nullable Intent build() {
73        if (DEBUG) Log.d(TAG, "Preparing intent for doc:" + mDocument.documentId);
74
75        String trustedPkg = mResources.getString(R.string.trusted_quick_viewer_package);
76
77        if (!TextUtils.isEmpty(trustedPkg)) {
78            Intent intent = new Intent(Intent.ACTION_QUICK_VIEW);
79            intent.setDataAndType(mDocument.derivedUri, mDocument.mimeType);
80            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
81            intent.setPackage(trustedPkg);
82            if (hasRegisteredHandler(intent)) {
83                List<String> siblingIds = mModel.getModelIds();
84                for (int i = 0; i < siblingIds.size(); i++) {
85                    onNextItem(i, siblingIds);
86                }
87                intent.putExtra(Intent.EXTRA_INDEX, mDocumentLocation);
88                intent.setClipData(mClipData);
89
90                return intent;
91            } else {
92                Log.e(TAG, "Can't resolve trusted quick view package: " + trustedPkg);
93            }
94        }
95
96        return null;
97    }
98
99    private boolean hasRegisteredHandler(Intent intent) {
100        // Try to resolve the intent. If a matching app isn't installed, it won't resolve.
101        return intent.resolveActivity(mPkgManager) != null;
102    }
103
104    private void onNextItem(int index, List<String> siblingIds) {
105        final Cursor cursor = mModel.getItem(siblingIds.get(index));
106
107        if (cursor == null) {
108            return;
109        }
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