157f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project/*
257f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project *
457f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
557f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project * you may not use this file except in compliance with the License.
657f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project * You may obtain a copy of the License at
757f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project *
857f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
957f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project *
1057f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1157f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1257f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project * See the License for the specific language governing permissions and
1457f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project * limitations under the License.
1557f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project */
1657f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project
1757f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Projectpackage com.android.providers.downloads;
1857f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project
19b3597b9d2fdde31bb0a8af821e3da3ca786e277bJeff Sharkeyimport static android.provider.Downloads.Impl.VISIBILITY_VISIBLE;
20b3597b9d2fdde31bb0a8af821e3da3ca786e277bJeff Sharkeyimport static android.provider.Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED;
21b3597b9d2fdde31bb0a8af821e3da3ca786e277bJeff Sharkey
22ed30deae5fe5b9de142b44933001c9b098c47712Jeff Sharkeyimport static com.android.providers.downloads.Constants.TAG;
23ed30deae5fe5b9de142b44933001c9b098c47712Jeff Sharkey
2414961f94d762e733a733e3268fca1074d8da5f8cSteve Howardimport android.app.DownloadManager;
253a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkeyimport android.app.job.JobInfo;
263398db8f3b195959faa2a7cf09918f364432ac28Steve Howardimport android.content.ContentResolver;
27071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howardimport android.content.ContentUris;
2857f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Projectimport android.content.Context;
2957f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Projectimport android.content.Intent;
305224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howardimport android.database.Cursor;
31c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queruimport android.net.Uri;
32789745f667c65661d82ccbd5ef49fdb132911736Vasu Noriimport android.os.Environment;
3357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Projectimport android.provider.Downloads;
34e00c31208405bd2e4c88e069df7a2b15237f70bfVasu Noriimport android.text.TextUtils;
353a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkeyimport android.text.format.DateUtils;
36ed30deae5fe5b9de142b44933001c9b098c47712Jeff Sharkeyimport android.util.Log;
37ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howardimport android.util.Pair;
3857f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project
396da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkeyimport com.android.internal.util.IndentingPrintWriter;
406da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey
41dffbb9c4567e9d29d19964a83129e38dceab7055Jeff Sharkeyimport java.io.CharArrayWriter;
42ed30deae5fe5b9de142b44933001c9b098c47712Jeff Sharkeyimport java.io.File;
43ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howardimport java.util.ArrayList;
44ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howardimport java.util.Collection;
455224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howardimport java.util.Collections;
46ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howardimport java.util.List;
475224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howard
4857f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project/**
49dffbb9c4567e9d29d19964a83129e38dceab7055Jeff Sharkey * Details about a specific download. Fields should only be mutated by updating
50dffbb9c4567e9d29d19964a83129e38dceab7055Jeff Sharkey * from database query.
5157f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project */
5257f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Projectpublic class DownloadInfo {
530de55602ec6d350548248feddc68c91b29326effJeff Sharkey    // TODO: move towards these in-memory objects being sources of truth, and
540de55602ec6d350548248feddc68c91b29326effJeff Sharkey    // periodically pushing to provider.
550de55602ec6d350548248feddc68c91b29326effJeff Sharkey
563398db8f3b195959faa2a7cf09918f364432ac28Steve Howard    public static class Reader {
573398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        private ContentResolver mResolver;
583398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        private Cursor mCursor;
593398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
603398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        public Reader(ContentResolver resolver, Cursor cursor) {
613398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            mResolver = resolver;
623398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            mCursor = cursor;
633398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        }
643398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
653398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        public void updateFromDatabase(DownloadInfo info) {
663398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mId = getLong(Downloads.Impl._ID);
671dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mUri = getString(Downloads.Impl.COLUMN_URI);
683398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mNoIntegrity = getInt(Downloads.Impl.COLUMN_NO_INTEGRITY) == 1;
691dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mHint = getString(Downloads.Impl.COLUMN_FILE_NAME_HINT);
701dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mFileName = getString(Downloads.Impl._DATA);
71dffbb9c4567e9d29d19964a83129e38dceab7055Jeff Sharkey            info.mMimeType = Intent.normalizeMimeType(getString(Downloads.Impl.COLUMN_MIME_TYPE));
723398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mDestination = getInt(Downloads.Impl.COLUMN_DESTINATION);
733398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mVisibility = getInt(Downloads.Impl.COLUMN_VISIBILITY);
743398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mStatus = getInt(Downloads.Impl.COLUMN_STATUS);
7512f5dc46aaa8e28cabfbe25d55f0af68f24ab306Jeff Sharkey            info.mNumFailed = getInt(Downloads.Impl.COLUMN_FAILED_CONNECTIONS);
763398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            int retryRedirect = getInt(Constants.RETRY_AFTER_X_REDIRECT_COUNT);
773398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mRetryAfter = retryRedirect & 0xfffffff;
783398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mLastMod = getLong(Downloads.Impl.COLUMN_LAST_MODIFICATION);
791dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mPackage = getString(Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE);
801dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mClass = getString(Downloads.Impl.COLUMN_NOTIFICATION_CLASS);
811dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mExtras = getString(Downloads.Impl.COLUMN_NOTIFICATION_EXTRAS);
821dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mCookies = getString(Downloads.Impl.COLUMN_COOKIE_DATA);
831dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mUserAgent = getString(Downloads.Impl.COLUMN_USER_AGENT);
841dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mReferer = getString(Downloads.Impl.COLUMN_REFERER);
853398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mTotalBytes = getLong(Downloads.Impl.COLUMN_TOTAL_BYTES);
863398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mCurrentBytes = getLong(Downloads.Impl.COLUMN_CURRENT_BYTES);
871dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mETag = getString(Constants.ETAG);
88665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey            info.mUid = getInt(Constants.UID);
89495edec1d9f7659923c71b009db66c1bd4782034Jeff Sharkey            info.mMediaScanned = getInt(Downloads.Impl.COLUMN_MEDIA_SCANNED);
90e00c31208405bd2e4c88e069df7a2b15237f70bfVasu Nori            info.mDeleted = getInt(Downloads.Impl.COLUMN_DELETED) == 1;
911dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mMediaProviderUri = getString(Downloads.Impl.COLUMN_MEDIAPROVIDER_URI);
923398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mIsPublicApi = getInt(Downloads.Impl.COLUMN_IS_PUBLIC_API) != 0;
933398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mAllowedNetworkTypes = getInt(Downloads.Impl.COLUMN_ALLOWED_NETWORK_TYPES);
943398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mAllowRoaming = getInt(Downloads.Impl.COLUMN_ALLOW_ROAMING) != 0;
95a7ae77fdae69bcc6d6609d4639fed5d96e55eeaaJeff Sharkey            info.mAllowMetered = getInt(Downloads.Impl.COLUMN_ALLOW_METERED) != 0;
963a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey            info.mFlags = getInt(Downloads.Impl.COLUMN_FLAGS);
971dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mTitle = getString(Downloads.Impl.COLUMN_TITLE);
981dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mDescription = getString(Downloads.Impl.COLUMN_DESCRIPTION);
99d319729622da1893e895f2e35f41d01ecdca3705Steve Howard            info.mBypassRecommendedSizeLimit =
100d319729622da1893e895f2e35f41d01ecdca3705Steve Howard                    getInt(Downloads.Impl.COLUMN_BYPASS_RECOMMENDED_SIZE_LIMIT);
1013398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
1023398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            synchronized (this) {
1033398db8f3b195959faa2a7cf09918f364432ac28Steve Howard                info.mControl = getInt(Downloads.Impl.COLUMN_CONTROL);
1043398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            }
1053398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        }
1063398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
1073a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey        public void readRequestHeaders(DownloadInfo info) {
1083398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mRequestHeaders.clear();
1093398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            Uri headerUri = Uri.withAppendedPath(
1103398db8f3b195959faa2a7cf09918f364432ac28Steve Howard                    info.getAllDownloadsUri(), Downloads.Impl.RequestHeaders.URI_SEGMENT);
1113398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            Cursor cursor = mResolver.query(headerUri, null, null, null, null);
1123398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            try {
1133398db8f3b195959faa2a7cf09918f364432ac28Steve Howard                int headerIndex =
1143398db8f3b195959faa2a7cf09918f364432ac28Steve Howard                        cursor.getColumnIndexOrThrow(Downloads.Impl.RequestHeaders.COLUMN_HEADER);
1153398db8f3b195959faa2a7cf09918f364432ac28Steve Howard                int valueIndex =
1163398db8f3b195959faa2a7cf09918f364432ac28Steve Howard                        cursor.getColumnIndexOrThrow(Downloads.Impl.RequestHeaders.COLUMN_VALUE);
1173398db8f3b195959faa2a7cf09918f364432ac28Steve Howard                for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
118ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard                    addHeader(info, cursor.getString(headerIndex), cursor.getString(valueIndex));
1193398db8f3b195959faa2a7cf09918f364432ac28Steve Howard                }
1203398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            } finally {
1213398db8f3b195959faa2a7cf09918f364432ac28Steve Howard                cursor.close();
1223398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            }
1233398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
1243398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            if (info.mCookies != null) {
125ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard                addHeader(info, "Cookie", info.mCookies);
1263398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            }
1273398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            if (info.mReferer != null) {
128ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard                addHeader(info, "Referer", info.mReferer);
1293398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            }
1303398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        }
1313398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
132ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard        private void addHeader(DownloadInfo info, String header, String value) {
133ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard            info.mRequestHeaders.add(Pair.create(header, value));
134ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard        }
135ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard
1361dc416983a4638a250b67b11564466088cfa41f6Vasu Nori        private String getString(String column) {
1373398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            int index = mCursor.getColumnIndexOrThrow(column);
1381dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            String s = mCursor.getString(index);
1391dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            return (TextUtils.isEmpty(s)) ? null : s;
1403398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        }
1413398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
1423398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        private Integer getInt(String column) {
1433398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            return mCursor.getInt(mCursor.getColumnIndexOrThrow(column));
1443398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        }
1453398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
1463398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        private Long getLong(String column) {
1473398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            return mCursor.getLong(mCursor.getColumnIndexOrThrow(column));
1483398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        }
1493398db8f3b195959faa2a7cf09918f364432ac28Steve Howard    }
1503398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
1513398db8f3b195959faa2a7cf09918f364432ac28Steve Howard    public long mId;
152c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public String mUri;
153dffbb9c4567e9d29d19964a83129e38dceab7055Jeff Sharkey    @Deprecated
154c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public boolean mNoIntegrity;
155c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public String mHint;
156c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public String mFileName;
157c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public String mMimeType;
158c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public int mDestination;
159c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public int mVisibility;
160c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public int mControl;
161c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public int mStatus;
162c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public int mNumFailed;
163c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public int mRetryAfter;
164c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public long mLastMod;
165c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public String mPackage;
166c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public String mClass;
167c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public String mExtras;
168c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public String mCookies;
169c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public String mUserAgent;
170c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public String mReferer;
171b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    public long mTotalBytes;
172b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    public long mCurrentBytes;
173c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public String mETag;
174665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey    public int mUid;
175b18ed519040c1ecd98f8cb139adcc315a3f4eedcVasu Nori    public int mMediaScanned;
176e00c31208405bd2e4c88e069df7a2b15237f70bfVasu Nori    public boolean mDeleted;
177e00c31208405bd2e4c88e069df7a2b15237f70bfVasu Nori    public String mMediaProviderUri;
1780a77c62a82503b38c484e0079648f0231dd85d53Steve Howard    public boolean mIsPublicApi;
1790a77c62a82503b38c484e0079648f0231dd85d53Steve Howard    public int mAllowedNetworkTypes;
1800a77c62a82503b38c484e0079648f0231dd85d53Steve Howard    public boolean mAllowRoaming;
181a7ae77fdae69bcc6d6609d4639fed5d96e55eeaaJeff Sharkey    public boolean mAllowMetered;
1823a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey    public int mFlags;
18397d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard    public String mTitle;
18497d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard    public String mDescription;
185d319729622da1893e895f2e35f41d01ecdca3705Steve Howard    public int mBypassRecommendedSizeLimit;
18657f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project
187ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard    private List<Pair<String, String>> mRequestHeaders = new ArrayList<Pair<String, String>>();
188071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard
189701d66efeff513a7509eeaafab6e47f4f6edb857Jeff Sharkey    private final Context mContext;
190701d66efeff513a7509eeaafab6e47f4f6edb857Jeff Sharkey    private final SystemFacade mSystemFacade;
191701d66efeff513a7509eeaafab6e47f4f6edb857Jeff Sharkey
1923a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey    public DownloadInfo(Context context) {
193071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard        mContext = context;
1943a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey        mSystemFacade = Helpers.getSystemFacade(context);
1953a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey    }
1963a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey
1973a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey    public static DownloadInfo queryDownloadInfo(Context context, long downloadId) {
1983a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey        final ContentResolver resolver = context.getContentResolver();
1993a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey        try (Cursor cursor = resolver.query(
2003a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey                ContentUris.withAppendedId(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, downloadId),
2013a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey                null, null, null, null)) {
2023a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey            final DownloadInfo.Reader reader = new DownloadInfo.Reader(resolver, cursor);
2033a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey            final DownloadInfo info = new DownloadInfo(context);
2043a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey            if (cursor.moveToFirst()) {
2053a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey                reader.updateFromDatabase(info);
2063a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey                reader.readRequestHeaders(info);
2073a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey                return info;
2083a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey            }
2093a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey        }
2103a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey        return null;
2115224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howard    }
21257f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project
213ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard    public Collection<Pair<String, String>> getHeaders() {
214ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard        return Collections.unmodifiableList(mRequestHeaders);
21557f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project    }
21657f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project
217dffbb9c4567e9d29d19964a83129e38dceab7055Jeff Sharkey    public String getUserAgent() {
218dffbb9c4567e9d29d19964a83129e38dceab7055Jeff Sharkey        if (mUserAgent != null) {
219dffbb9c4567e9d29d19964a83129e38dceab7055Jeff Sharkey            return mUserAgent;
220dffbb9c4567e9d29d19964a83129e38dceab7055Jeff Sharkey        } else {
221dffbb9c4567e9d29d19964a83129e38dceab7055Jeff Sharkey            return Constants.DEFAULT_USER_AGENT;
222dffbb9c4567e9d29d19964a83129e38dceab7055Jeff Sharkey        }
223dffbb9c4567e9d29d19964a83129e38dceab7055Jeff Sharkey    }
224dffbb9c4567e9d29d19964a83129e38dceab7055Jeff Sharkey
2253d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard    public void sendIntentIfRequested() {
2260a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        if (mPackage == null) {
2270a77c62a82503b38c484e0079648f0231dd85d53Steve Howard            return;
2280a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        }
2290a77c62a82503b38c484e0079648f0231dd85d53Steve Howard
2300a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        Intent intent;
2310a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        if (mIsPublicApi) {
2320a77c62a82503b38c484e0079648f0231dd85d53Steve Howard            intent = new Intent(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
2330a77c62a82503b38c484e0079648f0231dd85d53Steve Howard            intent.setPackage(mPackage);
2343398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            intent.putExtra(DownloadManager.EXTRA_DOWNLOAD_ID, mId);
2350a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        } else { // legacy behavior
2360a77c62a82503b38c484e0079648f0231dd85d53Steve Howard            if (mClass == null) {
2370a77c62a82503b38c484e0079648f0231dd85d53Steve Howard                return;
2380a77c62a82503b38c484e0079648f0231dd85d53Steve Howard            }
2390a77c62a82503b38c484e0079648f0231dd85d53Steve Howard            intent = new Intent(Downloads.Impl.ACTION_DOWNLOAD_COMPLETED);
240c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru            intent.setClassName(mPackage, mClass);
241c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru            if (mExtras != null) {
2427dd92fa94df0a13b4592ee636b7aa2b605f6b473Jean-Baptiste Queru                intent.putExtra(Downloads.Impl.COLUMN_NOTIFICATION_EXTRAS, mExtras);
24357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project            }
24457f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project            // We only send the content: URI, for security reasons. Otherwise, malicious
24557f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project            //     applications would have an easier time spoofing download results by
24657f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project            //     sending spoofed intents.
2473d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard            intent.setData(getMyDownloadsUri());
24857f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project        }
2490a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        mSystemFacade.sendBroadcast(intent);
25057f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project    }
25157f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project
25257f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project    /**
253b3597b9d2fdde31bb0a8af821e3da3ca786e277bJeff Sharkey     * Return if this download is visible to the user while running.
254b3597b9d2fdde31bb0a8af821e3da3ca786e277bJeff Sharkey     */
255b3597b9d2fdde31bb0a8af821e3da3ca786e277bJeff Sharkey    public boolean isVisible() {
256b3597b9d2fdde31bb0a8af821e3da3ca786e277bJeff Sharkey        switch (mVisibility) {
257b3597b9d2fdde31bb0a8af821e3da3ca786e277bJeff Sharkey            case VISIBILITY_VISIBLE:
258b3597b9d2fdde31bb0a8af821e3da3ca786e277bJeff Sharkey            case VISIBILITY_VISIBLE_NOTIFY_COMPLETED:
259b3597b9d2fdde31bb0a8af821e3da3ca786e277bJeff Sharkey                return true;
260b3597b9d2fdde31bb0a8af821e3da3ca786e277bJeff Sharkey            default:
261b3597b9d2fdde31bb0a8af821e3da3ca786e277bJeff Sharkey                return false;
262b3597b9d2fdde31bb0a8af821e3da3ca786e277bJeff Sharkey        }
263b3597b9d2fdde31bb0a8af821e3da3ca786e277bJeff Sharkey    }
264b3597b9d2fdde31bb0a8af821e3da3ca786e277bJeff Sharkey
265b3597b9d2fdde31bb0a8af821e3da3ca786e277bJeff Sharkey    /**
2663a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey     * Add random fuzz to the given delay so it's anywhere between 1-1.5x the
2673a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey     * requested delay.
2683a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey     */
2693a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey    private long fuzzDelay(long delay) {
2703a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey        return delay + Helpers.sRandom.nextInt((int) (delay / 2));
2713a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey    }
2723a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey
2733a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey    /**
2743a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey     * Return minimum latency in milliseconds required before this download is
2753a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey     * allowed to start again.
2763a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey     *
2773a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey     * @see android.app.job.JobInfo.Builder#setMinimumLatency(long)
2783a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey     */
2793a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey    public long getMinimumLatency() {
2803a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey        if (mStatus == Downloads.Impl.STATUS_WAITING_TO_RETRY) {
2813a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey            final long now = mSystemFacade.currentTimeMillis();
2823a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey            final long startAfter;
2833a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey            if (mNumFailed == 0) {
2843a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey                startAfter = now;
2853a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey            } else if (mRetryAfter > 0) {
2863a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey                startAfter = mLastMod + fuzzDelay(mRetryAfter);
2873a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey            } else {
2883a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey                final long delay = (Constants.RETRY_FIRST_DELAY * DateUtils.SECOND_IN_MILLIS
2893a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey                        * (1 << (mNumFailed - 1)));
2903a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey                startAfter = mLastMod + fuzzDelay(delay);
2913a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey            }
2923a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey            return Math.max(0, startAfter - now);
2933a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey        } else {
2943a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey            return 0;
2953a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey        }
2963a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey    }
2973a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey
2983a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey    /**
2993a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey     * Return the network type constraint required by this download.
3003a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey     *
3013a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey     * @see android.app.job.JobInfo.Builder#setRequiredNetworkType(int)
30257f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project     */
3033a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey    public int getRequiredNetworkType(long totalBytes) {
3043a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey        if (!mAllowMetered) {
3053a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey            return JobInfo.NETWORK_TYPE_UNMETERED;
3063a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey        }
3073a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey        if (mAllowedNetworkTypes == DownloadManager.Request.NETWORK_WIFI) {
3083a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey            return JobInfo.NETWORK_TYPE_UNMETERED;
309b108a273b150e81bf26553b8851d6241bc711f98Steve Howard        }
3103a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey        if (totalBytes > mSystemFacade.getMaxBytesOverMobile()) {
3113a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey            return JobInfo.NETWORK_TYPE_UNMETERED;
3121fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project        }
3133a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey        if (totalBytes > mSystemFacade.getRecommendedMaxBytesOverMobile()
3143a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey                && mBypassRecommendedSizeLimit == 0) {
3153a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey            return JobInfo.NETWORK_TYPE_UNMETERED;
3163a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey        }
3173a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey        if (!mAllowRoaming) {
3183a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey            return JobInfo.NETWORK_TYPE_NOT_ROAMING;
3193a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey        }
3203a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey        return JobInfo.NETWORK_TYPE_ANY;
32157f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project    }
32257f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project
32357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project    /**
3243a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey     * Returns whether this download is ready to be scheduled.
32557f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project     */
3263a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey    public boolean isReadyToSchedule() {
3277dd92fa94df0a13b4592ee636b7aa2b605f6b473Jean-Baptiste Queru        if (mControl == Downloads.Impl.CONTROL_PAUSED) {
3281fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project            // the download is paused, so it's not going to start
3291fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project            return false;
3301fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project        }
331b108a273b150e81bf26553b8851d6241bc711f98Steve Howard        switch (mStatus) {
3323a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey            case 0:
3333a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey            case Downloads.Impl.STATUS_PENDING:
3343a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey            case Downloads.Impl.STATUS_RUNNING:
335b108a273b150e81bf26553b8851d6241bc711f98Steve Howard            case Downloads.Impl.STATUS_WAITING_FOR_NETWORK:
3363a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey            case Downloads.Impl.STATUS_WAITING_TO_RETRY:
337b108a273b150e81bf26553b8851d6241bc711f98Steve Howard            case Downloads.Impl.STATUS_QUEUED_FOR_WIFI:
3383a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey                return true;
339b108a273b150e81bf26553b8851d6241bc711f98Steve Howard
340789745f667c65661d82ccbd5ef49fdb132911736Vasu Nori            case Downloads.Impl.STATUS_DEVICE_NOT_FOUND_ERROR:
341789745f667c65661d82ccbd5ef49fdb132911736Vasu Nori                // is the media mounted?
342ed30deae5fe5b9de142b44933001c9b098c47712Jeff Sharkey                final Uri uri = Uri.parse(mUri);
343ed30deae5fe5b9de142b44933001c9b098c47712Jeff Sharkey                if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
344ed30deae5fe5b9de142b44933001c9b098c47712Jeff Sharkey                    final File file = new File(uri.getPath());
345ed30deae5fe5b9de142b44933001c9b098c47712Jeff Sharkey                    return Environment.MEDIA_MOUNTED
346ed30deae5fe5b9de142b44933001c9b098c47712Jeff Sharkey                            .equals(Environment.getExternalStorageState(file));
347ed30deae5fe5b9de142b44933001c9b098c47712Jeff Sharkey                } else {
348ed30deae5fe5b9de142b44933001c9b098c47712Jeff Sharkey                    Log.w(TAG, "Expected file URI on external storage: " + mUri);
349ed30deae5fe5b9de142b44933001c9b098c47712Jeff Sharkey                    return false;
350ed30deae5fe5b9de142b44933001c9b098c47712Jeff Sharkey                }
3513a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey
3523a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey            default:
353579be0d0d0de6af307ee94af07720a568ed2e7d1Hideki Hayami                return false;
35457f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project        }
35557f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project    }
35657f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project
35757f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project    /**
35857f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project     * Returns whether this download has a visible notification after
35957f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project     * completion.
36057f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project     */
36157f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project    public boolean hasCompletionNotification() {
3627dd92fa94df0a13b4592ee636b7aa2b605f6b473Jean-Baptiste Queru        if (!Downloads.Impl.isStatusCompleted(mStatus)) {
36357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project            return false;
36457f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project        }
3657dd92fa94df0a13b4592ee636b7aa2b605f6b473Jean-Baptiste Queru        if (mVisibility == Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) {
36657f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project            return true;
36757f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project        }
36857f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project        return false;
36957f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project    }
3701fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project
371b5ca499c7417fc5954b6914d6d52e6e2c02ce7d8Jeff Sharkey    public boolean isMeteredAllowed(long totalBytes) {
372b5ca499c7417fc5954b6914d6d52e6e2c02ce7d8Jeff Sharkey        return getRequiredNetworkType(totalBytes) != JobInfo.NETWORK_TYPE_UNMETERED;
373b5ca499c7417fc5954b6914d6d52e6e2c02ce7d8Jeff Sharkey    }
374b5ca499c7417fc5954b6914d6d52e6e2c02ce7d8Jeff Sharkey
3753a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey    public boolean isRoamingAllowed() {
3760a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        if (mIsPublicApi) {
3770a77c62a82503b38c484e0079648f0231dd85d53Steve Howard            return mAllowRoaming;
3780a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        } else { // legacy behavior
3790a77c62a82503b38c484e0079648f0231dd85d53Steve Howard            return mDestination != Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING;
3800a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        }
3810a77c62a82503b38c484e0079648f0231dd85d53Steve Howard    }
3820a77c62a82503b38c484e0079648f0231dd85d53Steve Howard
3833d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard    public Uri getMyDownloadsUri() {
3843d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard        return ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, mId);
3853d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard    }
3863d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard
3873d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard    public Uri getAllDownloadsUri() {
3883d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard        return ContentUris.withAppendedId(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, mId);
3893d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard    }
3903398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
391dffbb9c4567e9d29d19964a83129e38dceab7055Jeff Sharkey    @Override
392dffbb9c4567e9d29d19964a83129e38dceab7055Jeff Sharkey    public String toString() {
393dffbb9c4567e9d29d19964a83129e38dceab7055Jeff Sharkey        final CharArrayWriter writer = new CharArrayWriter();
394dffbb9c4567e9d29d19964a83129e38dceab7055Jeff Sharkey        dump(new IndentingPrintWriter(writer, "  "));
395dffbb9c4567e9d29d19964a83129e38dceab7055Jeff Sharkey        return writer.toString();
396dffbb9c4567e9d29d19964a83129e38dceab7055Jeff Sharkey    }
397dffbb9c4567e9d29d19964a83129e38dceab7055Jeff Sharkey
3986da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey    public void dump(IndentingPrintWriter pw) {
3996da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.println("DownloadInfo:");
4006da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.increaseIndent();
4016da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey
4026da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.printPair("mId", mId);
4036da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.printPair("mLastMod", mLastMod);
4046da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.printPair("mPackage", mPackage);
4056da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.printPair("mUid", mUid);
4066da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.println();
4076da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey
4086da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.printPair("mUri", mUri);
4096da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.println();
4106da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey
4116da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.printPair("mMimeType", mMimeType);
4126da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.printPair("mCookies", (mCookies != null) ? "yes" : "no");
4136da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.printPair("mReferer", (mReferer != null) ? "yes" : "no");
4146da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.printPair("mUserAgent", mUserAgent);
4156da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.println();
4166da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey
4176da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.printPair("mFileName", mFileName);
4186da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.printPair("mDestination", mDestination);
4196da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.println();
4206da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey
4216da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.printPair("mStatus", Downloads.Impl.statusToString(mStatus));
4226da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.printPair("mCurrentBytes", mCurrentBytes);
4236da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.printPair("mTotalBytes", mTotalBytes);
4246da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.println();
4256da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey
4266da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.printPair("mNumFailed", mNumFailed);
4276da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.printPair("mRetryAfter", mRetryAfter);
4286da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.printPair("mETag", mETag);
4296da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.printPair("mIsPublicApi", mIsPublicApi);
4306da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.println();
4316da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey
4326da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.printPair("mAllowedNetworkTypes", mAllowedNetworkTypes);
4336da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.printPair("mAllowRoaming", mAllowRoaming);
434a7ae77fdae69bcc6d6609d4639fed5d96e55eeaaJeff Sharkey        pw.printPair("mAllowMetered", mAllowMetered);
4353a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey        pw.printPair("mFlags", mFlags);
4366da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.println();
4376da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey
4386da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey        pw.decreaseIndent();
4393398db8f3b195959faa2a7cf09918f364432ac28Steve Howard    }
4403398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
4413398db8f3b195959faa2a7cf09918f364432ac28Steve Howard    /**
4423398db8f3b195959faa2a7cf09918f364432ac28Steve Howard     * Returns whether a file should be scanned
4433398db8f3b195959faa2a7cf09918f364432ac28Steve Howard     */
4443a4a3e7cd5a379e7e757177826ba935f000eb455Jeff Sharkey    public boolean shouldScanFile(int status) {
445b18ed519040c1ecd98f8cb139adcc315a3f4eedcVasu Nori        return (mMediaScanned == 0)
446971525cbe68f83a4f05cfe942f774486702947a7Vasu Nori                && (mDestination == Downloads.Impl.DESTINATION_EXTERNAL ||
447b18ed519040c1ecd98f8cb139adcc315a3f4eedcVasu Nori                        mDestination == Downloads.Impl.DESTINATION_FILE_URI ||
448b18ed519040c1ecd98f8cb139adcc315a3f4eedcVasu Nori                        mDestination == Downloads.Impl.DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD)
4493a4a3e7cd5a379e7e757177826ba935f000eb455Jeff Sharkey                && Downloads.Impl.isStatusSuccess(status);
4503398db8f3b195959faa2a7cf09918f364432ac28Steve Howard    }
451d319729622da1893e895f2e35f41d01ecdca3705Steve Howard
4522fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey    /**
4532fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey     * Query and return status of requested download.
4542fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey     */
4553a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey    public int queryDownloadStatus() {
4563a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey        return queryDownloadInt(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_PENDING);
4573a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey    }
4583a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey
4593a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey    public int queryDownloadControl() {
4603a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey        return queryDownloadInt(Downloads.Impl.COLUMN_CONTROL, Downloads.Impl.CONTROL_RUN);
4613a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey    }
4623a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey
4633a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey    public int queryDownloadInt(String columnName, int defaultValue) {
4643a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey        try (Cursor cursor = mContext.getContentResolver().query(getAllDownloadsUri(),
4653a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey                new String[] { columnName }, null, null, null)) {
4662fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey            if (cursor.moveToFirst()) {
4672fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey                return cursor.getInt(0);
4682fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey            } else {
4693a5f5eafb34eaa4963c801882148e8f61514a61bJeff Sharkey                return defaultValue;
4702fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey            }
4712fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey        }
4722fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey    }
47357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project}
474