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
1914961f94d762e733a733e3268fca1074d8da5f8cSteve Howardimport android.app.DownloadManager;
203398db8f3b195959faa2a7cf09918f364432ac28Steve Howardimport android.content.ContentResolver;
21071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howardimport android.content.ContentUris;
22071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howardimport android.content.ContentValues;
2357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Projectimport android.content.Context;
2457f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Projectimport android.content.Intent;
255224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howardimport android.database.Cursor;
26071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howardimport android.net.ConnectivityManager;
27961024389b3782936a40a7d090d670290bb66c3cJeff Sharkeyimport android.net.NetworkInfo;
28961024389b3782936a40a7d090d670290bb66c3cJeff Sharkeyimport android.net.NetworkInfo.DetailedState;
29c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queruimport android.net.Uri;
30789745f667c65661d82ccbd5ef49fdb132911736Vasu Noriimport android.os.Environment;
3157f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Projectimport android.provider.Downloads;
32071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howardimport android.provider.Downloads.Impl;
33e00c31208405bd2e4c88e069df7a2b15237f70bfVasu Noriimport android.text.TextUtils;
34071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howardimport android.util.Log;
35ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howardimport android.util.Pair;
3657f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project
37665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkeyimport java.io.PrintWriter;
38ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howardimport java.util.ArrayList;
39ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howardimport java.util.Collection;
405224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howardimport java.util.Collections;
41ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howardimport java.util.List;
425224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howard
4357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project/**
4457f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project * Stores information about an individual download.
4557f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project */
4657f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Projectpublic class DownloadInfo {
473398db8f3b195959faa2a7cf09918f364432ac28Steve Howard    public static class Reader {
483398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        private ContentResolver mResolver;
493398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        private Cursor mCursor;
503398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
513398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        public Reader(ContentResolver resolver, Cursor cursor) {
523398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            mResolver = resolver;
533398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            mCursor = cursor;
543398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        }
553398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
563398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        public DownloadInfo newDownloadInfo(Context context, SystemFacade systemFacade) {
573398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            DownloadInfo info = new DownloadInfo(context, systemFacade);
583398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            updateFromDatabase(info);
593398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            readRequestHeaders(info);
603398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            return info;
613398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        }
623398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
633398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        public void updateFromDatabase(DownloadInfo info) {
643398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mId = getLong(Downloads.Impl._ID);
651dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mUri = getString(Downloads.Impl.COLUMN_URI);
663398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mNoIntegrity = getInt(Downloads.Impl.COLUMN_NO_INTEGRITY) == 1;
671dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mHint = getString(Downloads.Impl.COLUMN_FILE_NAME_HINT);
681dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mFileName = getString(Downloads.Impl._DATA);
691dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mMimeType = getString(Downloads.Impl.COLUMN_MIME_TYPE);
703398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mDestination = getInt(Downloads.Impl.COLUMN_DESTINATION);
713398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mVisibility = getInt(Downloads.Impl.COLUMN_VISIBILITY);
723398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mStatus = getInt(Downloads.Impl.COLUMN_STATUS);
733398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mNumFailed = getInt(Constants.FAILED_CONNECTIONS);
743398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            int retryRedirect = getInt(Constants.RETRY_AFTER_X_REDIRECT_COUNT);
753398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mRetryAfter = retryRedirect & 0xfffffff;
763398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mLastMod = getLong(Downloads.Impl.COLUMN_LAST_MODIFICATION);
771dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mPackage = getString(Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE);
781dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mClass = getString(Downloads.Impl.COLUMN_NOTIFICATION_CLASS);
791dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mExtras = getString(Downloads.Impl.COLUMN_NOTIFICATION_EXTRAS);
801dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mCookies = getString(Downloads.Impl.COLUMN_COOKIE_DATA);
811dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mUserAgent = getString(Downloads.Impl.COLUMN_USER_AGENT);
821dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mReferer = getString(Downloads.Impl.COLUMN_REFERER);
833398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mTotalBytes = getLong(Downloads.Impl.COLUMN_TOTAL_BYTES);
843398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mCurrentBytes = getLong(Downloads.Impl.COLUMN_CURRENT_BYTES);
851dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mETag = getString(Constants.ETAG);
86665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey            info.mUid = getInt(Constants.UID);
87b18ed519040c1ecd98f8cb139adcc315a3f4eedcVasu Nori            info.mMediaScanned = getInt(Constants.MEDIA_SCANNED);
88e00c31208405bd2e4c88e069df7a2b15237f70bfVasu Nori            info.mDeleted = getInt(Downloads.Impl.COLUMN_DELETED) == 1;
891dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mMediaProviderUri = getString(Downloads.Impl.COLUMN_MEDIAPROVIDER_URI);
903398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mIsPublicApi = getInt(Downloads.Impl.COLUMN_IS_PUBLIC_API) != 0;
913398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mAllowedNetworkTypes = getInt(Downloads.Impl.COLUMN_ALLOWED_NETWORK_TYPES);
923398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mAllowRoaming = getInt(Downloads.Impl.COLUMN_ALLOW_ROAMING) != 0;
931dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mTitle = getString(Downloads.Impl.COLUMN_TITLE);
941dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            info.mDescription = getString(Downloads.Impl.COLUMN_DESCRIPTION);
95d319729622da1893e895f2e35f41d01ecdca3705Steve Howard            info.mBypassRecommendedSizeLimit =
96d319729622da1893e895f2e35f41d01ecdca3705Steve Howard                    getInt(Downloads.Impl.COLUMN_BYPASS_RECOMMENDED_SIZE_LIMIT);
973398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
983398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            synchronized (this) {
993398db8f3b195959faa2a7cf09918f364432ac28Steve Howard                info.mControl = getInt(Downloads.Impl.COLUMN_CONTROL);
1003398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            }
1013398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        }
1023398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
1033398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        private void readRequestHeaders(DownloadInfo info) {
1043398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            info.mRequestHeaders.clear();
1053398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            Uri headerUri = Uri.withAppendedPath(
1063398db8f3b195959faa2a7cf09918f364432ac28Steve Howard                    info.getAllDownloadsUri(), Downloads.Impl.RequestHeaders.URI_SEGMENT);
1073398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            Cursor cursor = mResolver.query(headerUri, null, null, null, null);
1083398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            try {
1093398db8f3b195959faa2a7cf09918f364432ac28Steve Howard                int headerIndex =
1103398db8f3b195959faa2a7cf09918f364432ac28Steve Howard                        cursor.getColumnIndexOrThrow(Downloads.Impl.RequestHeaders.COLUMN_HEADER);
1113398db8f3b195959faa2a7cf09918f364432ac28Steve Howard                int valueIndex =
1123398db8f3b195959faa2a7cf09918f364432ac28Steve Howard                        cursor.getColumnIndexOrThrow(Downloads.Impl.RequestHeaders.COLUMN_VALUE);
1133398db8f3b195959faa2a7cf09918f364432ac28Steve Howard                for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
114ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard                    addHeader(info, cursor.getString(headerIndex), cursor.getString(valueIndex));
1153398db8f3b195959faa2a7cf09918f364432ac28Steve Howard                }
1163398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            } finally {
1173398db8f3b195959faa2a7cf09918f364432ac28Steve Howard                cursor.close();
1183398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            }
1193398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
1203398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            if (info.mCookies != null) {
121ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard                addHeader(info, "Cookie", info.mCookies);
1223398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            }
1233398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            if (info.mReferer != null) {
124ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard                addHeader(info, "Referer", info.mReferer);
1253398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            }
1263398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        }
1273398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
128ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard        private void addHeader(DownloadInfo info, String header, String value) {
129ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard            info.mRequestHeaders.add(Pair.create(header, value));
130ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard        }
131ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard
1321dc416983a4638a250b67b11564466088cfa41f6Vasu Nori        private String getString(String column) {
1333398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            int index = mCursor.getColumnIndexOrThrow(column);
1341dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            String s = mCursor.getString(index);
1351dc416983a4638a250b67b11564466088cfa41f6Vasu Nori            return (TextUtils.isEmpty(s)) ? null : s;
1363398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        }
1373398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
1383398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        private Integer getInt(String column) {
1393398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            return mCursor.getInt(mCursor.getColumnIndexOrThrow(column));
1403398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        }
1413398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
1423398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        private Long getLong(String column) {
1433398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            return mCursor.getLong(mCursor.getColumnIndexOrThrow(column));
1443398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        }
1453398db8f3b195959faa2a7cf09918f364432ac28Steve Howard    }
1463398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
147d319729622da1893e895f2e35f41d01ecdca3705Steve Howard    // the following NETWORK_* constants are used to indicates specfic reasons for disallowing a
148d319729622da1893e895f2e35f41d01ecdca3705Steve Howard    // download from using a network, since specific causes can require special handling
149d319729622da1893e895f2e35f41d01ecdca3705Steve Howard
150d319729622da1893e895f2e35f41d01ecdca3705Steve Howard    /**
151d319729622da1893e895f2e35f41d01ecdca3705Steve Howard     * The network is usable for the given download.
152d319729622da1893e895f2e35f41d01ecdca3705Steve Howard     */
153d319729622da1893e895f2e35f41d01ecdca3705Steve Howard    public static final int NETWORK_OK = 1;
154d319729622da1893e895f2e35f41d01ecdca3705Steve Howard
155d319729622da1893e895f2e35f41d01ecdca3705Steve Howard    /**
15626604ffc248081b8014ff7260536d18b43cb0de9Steve Howard     * There is no network connectivity.
157d319729622da1893e895f2e35f41d01ecdca3705Steve Howard     */
15826604ffc248081b8014ff7260536d18b43cb0de9Steve Howard    public static final int NETWORK_NO_CONNECTION = 2;
159d319729622da1893e895f2e35f41d01ecdca3705Steve Howard
160d319729622da1893e895f2e35f41d01ecdca3705Steve Howard    /**
161d319729622da1893e895f2e35f41d01ecdca3705Steve Howard     * The download exceeds the maximum size for this network.
162d319729622da1893e895f2e35f41d01ecdca3705Steve Howard     */
163d319729622da1893e895f2e35f41d01ecdca3705Steve Howard    public static final int NETWORK_UNUSABLE_DUE_TO_SIZE = 3;
164d319729622da1893e895f2e35f41d01ecdca3705Steve Howard
165d319729622da1893e895f2e35f41d01ecdca3705Steve Howard    /**
166d319729622da1893e895f2e35f41d01ecdca3705Steve Howard     * The download exceeds the recommended maximum size for this network, the user must confirm for
167d319729622da1893e895f2e35f41d01ecdca3705Steve Howard     * this download to proceed without WiFi.
168d319729622da1893e895f2e35f41d01ecdca3705Steve Howard     */
169d319729622da1893e895f2e35f41d01ecdca3705Steve Howard    public static final int NETWORK_RECOMMENDED_UNUSABLE_DUE_TO_SIZE = 4;
170d319729622da1893e895f2e35f41d01ecdca3705Steve Howard
171d319729622da1893e895f2e35f41d01ecdca3705Steve Howard    /**
17226604ffc248081b8014ff7260536d18b43cb0de9Steve Howard     * The current connection is roaming, and the download can't proceed over a roaming connection.
17326604ffc248081b8014ff7260536d18b43cb0de9Steve Howard     */
17426604ffc248081b8014ff7260536d18b43cb0de9Steve Howard    public static final int NETWORK_CANNOT_USE_ROAMING = 5;
17526604ffc248081b8014ff7260536d18b43cb0de9Steve Howard
17626604ffc248081b8014ff7260536d18b43cb0de9Steve Howard    /**
17726604ffc248081b8014ff7260536d18b43cb0de9Steve Howard     * The app requesting the download specific that it can't use the current network connection.
17826604ffc248081b8014ff7260536d18b43cb0de9Steve Howard     */
17926604ffc248081b8014ff7260536d18b43cb0de9Steve Howard    public static final int NETWORK_TYPE_DISALLOWED_BY_REQUESTOR = 6;
18026604ffc248081b8014ff7260536d18b43cb0de9Steve Howard
18126604ffc248081b8014ff7260536d18b43cb0de9Steve Howard    /**
182961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey     * Current network is blocked for requesting application.
183961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey     */
184961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey    public static final int NETWORK_BLOCKED = 7;
185961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey
186961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey    /**
187d319729622da1893e895f2e35f41d01ecdca3705Steve Howard     * For intents used to notify the user that a download exceeds a size threshold, if this extra
188d319729622da1893e895f2e35f41d01ecdca3705Steve Howard     * is true, WiFi is required for this download size; otherwise, it is only recommended.
189d319729622da1893e895f2e35f41d01ecdca3705Steve Howard     */
190d319729622da1893e895f2e35f41d01ecdca3705Steve Howard    public static final String EXTRA_IS_WIFI_REQUIRED = "isWifiRequired";
191d319729622da1893e895f2e35f41d01ecdca3705Steve Howard
192d319729622da1893e895f2e35f41d01ecdca3705Steve Howard
1933398db8f3b195959faa2a7cf09918f364432ac28Steve Howard    public long mId;
194c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public String mUri;
195c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public boolean mNoIntegrity;
196c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public String mHint;
197c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public String mFileName;
198c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public String mMimeType;
199c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public int mDestination;
200c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public int mVisibility;
201c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public int mControl;
202c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public int mStatus;
203c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public int mNumFailed;
204c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public int mRetryAfter;
205c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public long mLastMod;
206c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public String mPackage;
207c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public String mClass;
208c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public String mExtras;
209c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public String mCookies;
210c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public String mUserAgent;
211c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public String mReferer;
212b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    public long mTotalBytes;
213b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    public long mCurrentBytes;
214c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru    public String mETag;
215665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey    public int mUid;
216b18ed519040c1ecd98f8cb139adcc315a3f4eedcVasu Nori    public int mMediaScanned;
217e00c31208405bd2e4c88e069df7a2b15237f70bfVasu Nori    public boolean mDeleted;
218e00c31208405bd2e4c88e069df7a2b15237f70bfVasu Nori    public String mMediaProviderUri;
2190a77c62a82503b38c484e0079648f0231dd85d53Steve Howard    public boolean mIsPublicApi;
2200a77c62a82503b38c484e0079648f0231dd85d53Steve Howard    public int mAllowedNetworkTypes;
2210a77c62a82503b38c484e0079648f0231dd85d53Steve Howard    public boolean mAllowRoaming;
22297d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard    public String mTitle;
22397d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard    public String mDescription;
224d319729622da1893e895f2e35f41d01ecdca3705Steve Howard    public int mBypassRecommendedSizeLimit;
22557f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project
2264a977a52c3eb3ac08b94b81aef72fb618be39f81Jean-Baptiste Queru    public int mFuzz;
2274a977a52c3eb3ac08b94b81aef72fb618be39f81Jean-Baptiste Queru
228ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard    private List<Pair<String, String>> mRequestHeaders = new ArrayList<Pair<String, String>>();
229071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard    private SystemFacade mSystemFacade;
230071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard    private Context mContext;
231071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard
2323398db8f3b195959faa2a7cf09918f364432ac28Steve Howard    private DownloadInfo(Context context, SystemFacade systemFacade) {
233071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard        mContext = context;
234071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard        mSystemFacade = systemFacade;
2355224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howard        mFuzz = Helpers.sRandom.nextInt(1001);
2365224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howard    }
23757f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project
238ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard    public Collection<Pair<String, String>> getHeaders() {
239ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard        return Collections.unmodifiableList(mRequestHeaders);
24057f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project    }
24157f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project
2423d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard    public void sendIntentIfRequested() {
2430a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        if (mPackage == null) {
2440a77c62a82503b38c484e0079648f0231dd85d53Steve Howard            return;
2450a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        }
2460a77c62a82503b38c484e0079648f0231dd85d53Steve Howard
2470a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        Intent intent;
2480a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        if (mIsPublicApi) {
2490a77c62a82503b38c484e0079648f0231dd85d53Steve Howard            intent = new Intent(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
2500a77c62a82503b38c484e0079648f0231dd85d53Steve Howard            intent.setPackage(mPackage);
2513398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            intent.putExtra(DownloadManager.EXTRA_DOWNLOAD_ID, mId);
2520a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        } else { // legacy behavior
2530a77c62a82503b38c484e0079648f0231dd85d53Steve Howard            if (mClass == null) {
2540a77c62a82503b38c484e0079648f0231dd85d53Steve Howard                return;
2550a77c62a82503b38c484e0079648f0231dd85d53Steve Howard            }
2560a77c62a82503b38c484e0079648f0231dd85d53Steve Howard            intent = new Intent(Downloads.Impl.ACTION_DOWNLOAD_COMPLETED);
257c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru            intent.setClassName(mPackage, mClass);
258c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru            if (mExtras != null) {
2597dd92fa94df0a13b4592ee636b7aa2b605f6b473Jean-Baptiste Queru                intent.putExtra(Downloads.Impl.COLUMN_NOTIFICATION_EXTRAS, mExtras);
26057f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project            }
26157f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project            // We only send the content: URI, for security reasons. Otherwise, malicious
26257f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project            //     applications would have an easier time spoofing download results by
26357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project            //     sending spoofed intents.
2643d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard            intent.setData(getMyDownloadsUri());
26557f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project        }
2660a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        mSystemFacade.sendBroadcast(intent);
26757f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project    }
26857f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project
26957f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project    /**
270b108a273b150e81bf26553b8851d6241bc711f98Steve Howard     * Returns the time when a download should be restarted.
27157f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project     */
272b108a273b150e81bf26553b8851d6241bc711f98Steve Howard    public long restartTime(long now) {
273b108a273b150e81bf26553b8851d6241bc711f98Steve Howard        if (mNumFailed == 0) {
274b108a273b150e81bf26553b8851d6241bc711f98Steve Howard            return now;
275b108a273b150e81bf26553b8851d6241bc711f98Steve Howard        }
276c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru        if (mRetryAfter > 0) {
277c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru            return mLastMod + mRetryAfter;
2781fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project        }
279c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru        return mLastMod +
2801fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project                Constants.RETRY_FIRST_DELAY *
2814a977a52c3eb3ac08b94b81aef72fb618be39f81Jean-Baptiste Queru                    (1000 + mFuzz) * (1 << (mNumFailed - 1));
28257f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project    }
28357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project
28457f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project    /**
2851fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project     * Returns whether this download (which the download manager hasn't seen yet)
2861fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project     * should be started.
28757f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project     */
288b108a273b150e81bf26553b8851d6241bc711f98Steve Howard    private boolean isReadyToStart(long now) {
2896baceb7073ed7858d3424ccf774e5f6a946bec59Vasu Nori        if (DownloadHandler.getInstance().hasDownloadInQueue(mId)) {
290b108a273b150e81bf26553b8851d6241bc711f98Steve Howard            // already running
291b108a273b150e81bf26553b8851d6241bc711f98Steve Howard            return false;
292b108a273b150e81bf26553b8851d6241bc711f98Steve Howard        }
2937dd92fa94df0a13b4592ee636b7aa2b605f6b473Jean-Baptiste Queru        if (mControl == Downloads.Impl.CONTROL_PAUSED) {
2941fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project            // the download is paused, so it's not going to start
2951fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project            return false;
2961fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project        }
297b108a273b150e81bf26553b8851d6241bc711f98Steve Howard        switch (mStatus) {
298b108a273b150e81bf26553b8851d6241bc711f98Steve Howard            case 0: // status hasn't been initialized yet, this is a new download
299b108a273b150e81bf26553b8851d6241bc711f98Steve Howard            case Downloads.Impl.STATUS_PENDING: // download is explicit marked as ready to start
300b108a273b150e81bf26553b8851d6241bc711f98Steve Howard            case Downloads.Impl.STATUS_RUNNING: // download interrupted (process killed etc) while
301b108a273b150e81bf26553b8851d6241bc711f98Steve Howard                                                // running, without a chance to update the database
30257f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project                return true;
30357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project
304b108a273b150e81bf26553b8851d6241bc711f98Steve Howard            case Downloads.Impl.STATUS_WAITING_FOR_NETWORK:
305b108a273b150e81bf26553b8851d6241bc711f98Steve Howard            case Downloads.Impl.STATUS_QUEUED_FOR_WIFI:
306d319729622da1893e895f2e35f41d01ecdca3705Steve Howard                return checkCanUseNetwork() == NETWORK_OK;
307b108a273b150e81bf26553b8851d6241bc711f98Steve Howard
308b108a273b150e81bf26553b8851d6241bc711f98Steve Howard            case Downloads.Impl.STATUS_WAITING_TO_RETRY:
309b108a273b150e81bf26553b8851d6241bc711f98Steve Howard                // download was waiting for a delayed restart
310b108a273b150e81bf26553b8851d6241bc711f98Steve Howard                return restartTime(now) <= now;
311789745f667c65661d82ccbd5ef49fdb132911736Vasu Nori            case Downloads.Impl.STATUS_DEVICE_NOT_FOUND_ERROR:
312789745f667c65661d82ccbd5ef49fdb132911736Vasu Nori                // is the media mounted?
313789745f667c65661d82ccbd5ef49fdb132911736Vasu Nori                return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
314789745f667c65661d82ccbd5ef49fdb132911736Vasu Nori            case Downloads.Impl.STATUS_INSUFFICIENT_SPACE_ERROR:
315789745f667c65661d82ccbd5ef49fdb132911736Vasu Nori                // should check space to make sure it is worth retrying the download.
316789745f667c65661d82ccbd5ef49fdb132911736Vasu Nori                // but thats the first thing done by the thread when it retries to download
317789745f667c65661d82ccbd5ef49fdb132911736Vasu Nori                // it will fail pretty quickly if there is no space.
318789745f667c65661d82ccbd5ef49fdb132911736Vasu Nori                // so, it is not that bad to skip checking space availability here.
319789745f667c65661d82ccbd5ef49fdb132911736Vasu Nori                return true;
32057f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project        }
32157f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project        return false;
32257f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project    }
32357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project
32457f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project    /**
32557f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project     * Returns whether this download has a visible notification after
32657f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project     * completion.
32757f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project     */
32857f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project    public boolean hasCompletionNotification() {
3297dd92fa94df0a13b4592ee636b7aa2b605f6b473Jean-Baptiste Queru        if (!Downloads.Impl.isStatusCompleted(mStatus)) {
33057f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project            return false;
33157f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project        }
3327dd92fa94df0a13b4592ee636b7aa2b605f6b473Jean-Baptiste Queru        if (mVisibility == Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) {
33357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project            return true;
33457f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project        }
33557f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project        return false;
33657f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project    }
3371fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project
3381fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project    /**
3391fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project     * Returns whether this download is allowed to use the network.
340d319729622da1893e895f2e35f41d01ecdca3705Steve Howard     * @return one of the NETWORK_* constants
3411fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project     */
342d319729622da1893e895f2e35f41d01ecdca3705Steve Howard    public int checkCanUseNetwork() {
343961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey        final NetworkInfo info = mSystemFacade.getActiveNetworkInfo(mUid);
344961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey        if (info == null) {
34526604ffc248081b8014ff7260536d18b43cb0de9Steve Howard            return NETWORK_NO_CONNECTION;
346071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard        }
347961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey        if (DetailedState.BLOCKED.equals(info.getDetailedState())) {
348961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey            return NETWORK_BLOCKED;
349961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey        }
3500a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        if (!isRoamingAllowed() && mSystemFacade.isNetworkRoaming()) {
35126604ffc248081b8014ff7260536d18b43cb0de9Steve Howard            return NETWORK_CANNOT_USE_ROAMING;
352071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard        }
353961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey        return checkIsNetworkTypeAllowed(info.getType());
354071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard    }
355071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard
3560a77c62a82503b38c484e0079648f0231dd85d53Steve Howard    private boolean isRoamingAllowed() {
3570a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        if (mIsPublicApi) {
3580a77c62a82503b38c484e0079648f0231dd85d53Steve Howard            return mAllowRoaming;
3590a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        } else { // legacy behavior
3600a77c62a82503b38c484e0079648f0231dd85d53Steve Howard            return mDestination != Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING;
3610a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        }
3620a77c62a82503b38c484e0079648f0231dd85d53Steve Howard    }
3630a77c62a82503b38c484e0079648f0231dd85d53Steve Howard
3640a77c62a82503b38c484e0079648f0231dd85d53Steve Howard    /**
36526604ffc248081b8014ff7260536d18b43cb0de9Steve Howard     * @return a non-localized string appropriate for logging corresponding to one of the
36626604ffc248081b8014ff7260536d18b43cb0de9Steve Howard     * NETWORK_* constants.
36726604ffc248081b8014ff7260536d18b43cb0de9Steve Howard     */
36826604ffc248081b8014ff7260536d18b43cb0de9Steve Howard    public String getLogMessageForNetworkError(int networkError) {
36926604ffc248081b8014ff7260536d18b43cb0de9Steve Howard        switch (networkError) {
37026604ffc248081b8014ff7260536d18b43cb0de9Steve Howard            case NETWORK_RECOMMENDED_UNUSABLE_DUE_TO_SIZE:
37126604ffc248081b8014ff7260536d18b43cb0de9Steve Howard                return "download size exceeds recommended limit for mobile network";
37226604ffc248081b8014ff7260536d18b43cb0de9Steve Howard
37326604ffc248081b8014ff7260536d18b43cb0de9Steve Howard            case NETWORK_UNUSABLE_DUE_TO_SIZE:
37426604ffc248081b8014ff7260536d18b43cb0de9Steve Howard                return "download size exceeds limit for mobile network";
37526604ffc248081b8014ff7260536d18b43cb0de9Steve Howard
37626604ffc248081b8014ff7260536d18b43cb0de9Steve Howard            case NETWORK_NO_CONNECTION:
37726604ffc248081b8014ff7260536d18b43cb0de9Steve Howard                return "no network connection available";
37826604ffc248081b8014ff7260536d18b43cb0de9Steve Howard
37926604ffc248081b8014ff7260536d18b43cb0de9Steve Howard            case NETWORK_CANNOT_USE_ROAMING:
38026604ffc248081b8014ff7260536d18b43cb0de9Steve Howard                return "download cannot use the current network connection because it is roaming";
38126604ffc248081b8014ff7260536d18b43cb0de9Steve Howard
38226604ffc248081b8014ff7260536d18b43cb0de9Steve Howard            case NETWORK_TYPE_DISALLOWED_BY_REQUESTOR:
38326604ffc248081b8014ff7260536d18b43cb0de9Steve Howard                return "download was requested to not use the current network type";
38426604ffc248081b8014ff7260536d18b43cb0de9Steve Howard
385961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey            case NETWORK_BLOCKED:
386961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey                return "network is blocked for requesting application";
387961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey
38826604ffc248081b8014ff7260536d18b43cb0de9Steve Howard            default:
38926604ffc248081b8014ff7260536d18b43cb0de9Steve Howard                return "unknown error with network connectivity";
39026604ffc248081b8014ff7260536d18b43cb0de9Steve Howard        }
39126604ffc248081b8014ff7260536d18b43cb0de9Steve Howard    }
39226604ffc248081b8014ff7260536d18b43cb0de9Steve Howard
39326604ffc248081b8014ff7260536d18b43cb0de9Steve Howard    /**
3940a77c62a82503b38c484e0079648f0231dd85d53Steve Howard     * Check if this download can proceed over the given network type.
3950a77c62a82503b38c484e0079648f0231dd85d53Steve Howard     * @param networkType a constant from ConnectivityManager.TYPE_*.
396d319729622da1893e895f2e35f41d01ecdca3705Steve Howard     * @return one of the NETWORK_* constants
3970a77c62a82503b38c484e0079648f0231dd85d53Steve Howard     */
398d319729622da1893e895f2e35f41d01ecdca3705Steve Howard    private int checkIsNetworkTypeAllowed(int networkType) {
3990a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        if (mIsPublicApi) {
4000a77c62a82503b38c484e0079648f0231dd85d53Steve Howard            int flag = translateNetworkTypeToApiFlag(networkType);
4010a77c62a82503b38c484e0079648f0231dd85d53Steve Howard            if ((flag & mAllowedNetworkTypes) == 0) {
40226604ffc248081b8014ff7260536d18b43cb0de9Steve Howard                return NETWORK_TYPE_DISALLOWED_BY_REQUESTOR;
4030a77c62a82503b38c484e0079648f0231dd85d53Steve Howard            }
4040a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        }
405d319729622da1893e895f2e35f41d01ecdca3705Steve Howard        return checkSizeAllowedForNetwork(networkType);
4060a77c62a82503b38c484e0079648f0231dd85d53Steve Howard    }
4070a77c62a82503b38c484e0079648f0231dd85d53Steve Howard
4080a77c62a82503b38c484e0079648f0231dd85d53Steve Howard    /**
4090a77c62a82503b38c484e0079648f0231dd85d53Steve Howard     * Translate a ConnectivityManager.TYPE_* constant to the corresponding
4100a77c62a82503b38c484e0079648f0231dd85d53Steve Howard     * DownloadManager.Request.NETWORK_* bit flag.
4110a77c62a82503b38c484e0079648f0231dd85d53Steve Howard     */
4120a77c62a82503b38c484e0079648f0231dd85d53Steve Howard    private int translateNetworkTypeToApiFlag(int networkType) {
4130a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        switch (networkType) {
4140a77c62a82503b38c484e0079648f0231dd85d53Steve Howard            case ConnectivityManager.TYPE_MOBILE:
4150a77c62a82503b38c484e0079648f0231dd85d53Steve Howard                return DownloadManager.Request.NETWORK_MOBILE;
4160a77c62a82503b38c484e0079648f0231dd85d53Steve Howard
4170a77c62a82503b38c484e0079648f0231dd85d53Steve Howard            case ConnectivityManager.TYPE_WIFI:
4180a77c62a82503b38c484e0079648f0231dd85d53Steve Howard                return DownloadManager.Request.NETWORK_WIFI;
4190a77c62a82503b38c484e0079648f0231dd85d53Steve Howard
4200a77c62a82503b38c484e0079648f0231dd85d53Steve Howard            default:
4210a77c62a82503b38c484e0079648f0231dd85d53Steve Howard                return 0;
4220a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        }
4230a77c62a82503b38c484e0079648f0231dd85d53Steve Howard    }
4240a77c62a82503b38c484e0079648f0231dd85d53Steve Howard
425071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard    /**
426071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard     * Check if the download's size prohibits it from running over the current network.
427d319729622da1893e895f2e35f41d01ecdca3705Steve Howard     * @return one of the NETWORK_* constants
428071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard     */
429d319729622da1893e895f2e35f41d01ecdca3705Steve Howard    private int checkSizeAllowedForNetwork(int networkType) {
430071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard        if (mTotalBytes <= 0) {
431d319729622da1893e895f2e35f41d01ecdca3705Steve Howard            return NETWORK_OK; // we don't know the size yet
432071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard        }
433071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard        if (networkType == ConnectivityManager.TYPE_WIFI) {
434d319729622da1893e895f2e35f41d01ecdca3705Steve Howard            return NETWORK_OK; // anything goes over wifi
435071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard        }
4360d4f9f105c3a31475a36e9a1edfa868c66ff455fSteve Howard        Long maxBytesOverMobile = mSystemFacade.getMaxBytesOverMobile();
437d319729622da1893e895f2e35f41d01ecdca3705Steve Howard        if (maxBytesOverMobile != null && mTotalBytes > maxBytesOverMobile) {
438d319729622da1893e895f2e35f41d01ecdca3705Steve Howard            return NETWORK_UNUSABLE_DUE_TO_SIZE;
439d319729622da1893e895f2e35f41d01ecdca3705Steve Howard        }
440d319729622da1893e895f2e35f41d01ecdca3705Steve Howard        if (mBypassRecommendedSizeLimit == 0) {
441d319729622da1893e895f2e35f41d01ecdca3705Steve Howard            Long recommendedMaxBytesOverMobile = mSystemFacade.getRecommendedMaxBytesOverMobile();
442d319729622da1893e895f2e35f41d01ecdca3705Steve Howard            if (recommendedMaxBytesOverMobile != null
443d319729622da1893e895f2e35f41d01ecdca3705Steve Howard                    && mTotalBytes > recommendedMaxBytesOverMobile) {
444d319729622da1893e895f2e35f41d01ecdca3705Steve Howard                return NETWORK_RECOMMENDED_UNUSABLE_DUE_TO_SIZE;
445d319729622da1893e895f2e35f41d01ecdca3705Steve Howard            }
446071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard        }
447d319729622da1893e895f2e35f41d01ecdca3705Steve Howard        return NETWORK_OK;
448071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard    }
449071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard
4505218d33d57990c3e3549c58bd3f0ac244dfc3d59Vasu Nori    void startIfReady(long now, StorageManager storageManager) {
451b108a273b150e81bf26553b8851d6241bc711f98Steve Howard        if (!isReadyToStart(now)) {
452b108a273b150e81bf26553b8851d6241bc711f98Steve Howard            return;
453b108a273b150e81bf26553b8851d6241bc711f98Steve Howard        }
454b108a273b150e81bf26553b8851d6241bc711f98Steve Howard
4555180de23e77139dd6971dfd48269242e3e3562d9Steve Howard        if (Constants.LOGV) {
4565180de23e77139dd6971dfd48269242e3e3562d9Steve Howard            Log.v(Constants.TAG, "Service spawning thread to handle download " + mId);
4575180de23e77139dd6971dfd48269242e3e3562d9Steve Howard        }
4585180de23e77139dd6971dfd48269242e3e3562d9Steve Howard        if (mStatus != Impl.STATUS_RUNNING) {
4595180de23e77139dd6971dfd48269242e3e3562d9Steve Howard            mStatus = Impl.STATUS_RUNNING;
4605180de23e77139dd6971dfd48269242e3e3562d9Steve Howard            ContentValues values = new ContentValues();
4615180de23e77139dd6971dfd48269242e3e3562d9Steve Howard            values.put(Impl.COLUMN_STATUS, mStatus);
4623d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard            mContext.getContentResolver().update(getAllDownloadsUri(), values, null, null);
4631fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project        }
4646baceb7073ed7858d3424ccf774e5f6a946bec59Vasu Nori        DownloadHandler.getInstance().enqueueDownload(this);
4651fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project    }
466adb6887d3270d180c94eaf90878d5b67d74a8f28Steve Howard
467adb6887d3270d180c94eaf90878d5b67d74a8f28Steve Howard    public boolean isOnCache() {
468adb6887d3270d180c94eaf90878d5b67d74a8f28Steve Howard        return (mDestination == Downloads.Impl.DESTINATION_CACHE_PARTITION
4699aadb4b3f2b3c914166ebfae8851fbecaf536f4fVasu Nori                || mDestination == Downloads.Impl.DESTINATION_SYSTEMCACHE_PARTITION
470adb6887d3270d180c94eaf90878d5b67d74a8f28Steve Howard                || mDestination == Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING
471adb6887d3270d180c94eaf90878d5b67d74a8f28Steve Howard                || mDestination == Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE);
472adb6887d3270d180c94eaf90878d5b67d74a8f28Steve Howard    }
4733d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard
4743d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard    public Uri getMyDownloadsUri() {
4753d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard        return ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, mId);
4763d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard    }
4773d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard
4783d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard    public Uri getAllDownloadsUri() {
4793d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard        return ContentUris.withAppendedId(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, mId);
4803d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard    }
4813398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
482665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey    public void dump(PrintWriter writer) {
483665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey        writer.println("DownloadInfo:");
4843398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
485665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey        writer.print("  mId="); writer.print(mId);
486665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey        writer.print(" mLastMod="); writer.print(mLastMod);
487665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey        writer.print(" mPackage="); writer.print(mPackage);
488665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey        writer.print(" mUid="); writer.println(mUid);
489665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey
490665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey        writer.print("  mUri="); writer.print(mUri);
491665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey        writer.print(" mMimeType="); writer.print(mMimeType);
492665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey        writer.print(" mCookies="); writer.print((mCookies != null) ? "yes" : "no");
493665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey        writer.print(" mReferer="); writer.println((mReferer != null) ? "yes" : "no");
494665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey
495665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey        writer.print("  mUserAgent="); writer.println(mUserAgent);
496665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey
497665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey        writer.print("  mFileName="); writer.println(mFileName);
498665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey
499665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey        writer.print("  mStatus="); writer.print(mStatus);
500665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey        writer.print(" mCurrentBytes="); writer.print(mCurrentBytes);
501665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey        writer.print(" mTotalBytes="); writer.println(mTotalBytes);
502665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey
503665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey        writer.print("  mNumFailed="); writer.print(mNumFailed);
504665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey        writer.print(" mRetryAfter="); writer.println(mRetryAfter);
5053398db8f3b195959faa2a7cf09918f364432ac28Steve Howard    }
5063398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
5073398db8f3b195959faa2a7cf09918f364432ac28Steve Howard    /**
5083398db8f3b195959faa2a7cf09918f364432ac28Steve Howard     * Returns the amount of time (as measured from the "now" parameter)
5093398db8f3b195959faa2a7cf09918f364432ac28Steve Howard     * at which a download will be active.
5103398db8f3b195959faa2a7cf09918f364432ac28Steve Howard     * 0 = immediately - service should stick around to handle this download.
5113398db8f3b195959faa2a7cf09918f364432ac28Steve Howard     * -1 = never - service can go away without ever waking up.
5123398db8f3b195959faa2a7cf09918f364432ac28Steve Howard     * positive value - service must wake up in the future, as specified in ms from "now"
5133398db8f3b195959faa2a7cf09918f364432ac28Steve Howard     */
5143398db8f3b195959faa2a7cf09918f364432ac28Steve Howard    long nextAction(long now) {
5153398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        if (Downloads.Impl.isStatusCompleted(mStatus)) {
5163398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            return -1;
5173398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        }
518b108a273b150e81bf26553b8851d6241bc711f98Steve Howard        if (mStatus != Downloads.Impl.STATUS_WAITING_TO_RETRY) {
5193398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            return 0;
5203398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        }
521b108a273b150e81bf26553b8851d6241bc711f98Steve Howard        long when = restartTime(now);
5223398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        if (when <= now) {
5233398db8f3b195959faa2a7cf09918f364432ac28Steve Howard            return 0;
5243398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        }
5253398db8f3b195959faa2a7cf09918f364432ac28Steve Howard        return when - now;
5263398db8f3b195959faa2a7cf09918f364432ac28Steve Howard    }
5273398db8f3b195959faa2a7cf09918f364432ac28Steve Howard
5283398db8f3b195959faa2a7cf09918f364432ac28Steve Howard    /**
5293398db8f3b195959faa2a7cf09918f364432ac28Steve Howard     * Returns whether a file should be scanned
5303398db8f3b195959faa2a7cf09918f364432ac28Steve Howard     */
5313398db8f3b195959faa2a7cf09918f364432ac28Steve Howard    boolean shouldScanFile() {
532b18ed519040c1ecd98f8cb139adcc315a3f4eedcVasu Nori        return (mMediaScanned == 0)
533971525cbe68f83a4f05cfe942f774486702947a7Vasu Nori                && (mDestination == Downloads.Impl.DESTINATION_EXTERNAL ||
534b18ed519040c1ecd98f8cb139adcc315a3f4eedcVasu Nori                        mDestination == Downloads.Impl.DESTINATION_FILE_URI ||
535b18ed519040c1ecd98f8cb139adcc315a3f4eedcVasu Nori                        mDestination == Downloads.Impl.DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD)
5360a17c2a28738d6ecb274def0e8e54f556d89f5f3Gloria Wang                && Downloads.Impl.isStatusSuccess(mStatus);
5373398db8f3b195959faa2a7cf09918f364432ac28Steve Howard    }
538d319729622da1893e895f2e35f41d01ecdca3705Steve Howard
539d319729622da1893e895f2e35f41d01ecdca3705Steve Howard    void notifyPauseDueToSize(boolean isWifiRequired) {
540d319729622da1893e895f2e35f41d01ecdca3705Steve Howard        Intent intent = new Intent(Intent.ACTION_VIEW);
541d319729622da1893e895f2e35f41d01ecdca3705Steve Howard        intent.setData(getAllDownloadsUri());
542d319729622da1893e895f2e35f41d01ecdca3705Steve Howard        intent.setClassName(SizeLimitActivity.class.getPackage().getName(),
543d319729622da1893e895f2e35f41d01ecdca3705Steve Howard                SizeLimitActivity.class.getName());
544d319729622da1893e895f2e35f41d01ecdca3705Steve Howard        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
545d319729622da1893e895f2e35f41d01ecdca3705Steve Howard        intent.putExtra(EXTRA_IS_WIFI_REQUIRED, isWifiRequired);
546d319729622da1893e895f2e35f41d01ecdca3705Steve Howard        mContext.startActivity(intent);
547d319729622da1893e895f2e35f41d01ecdca3705Steve Howard    }
5486baceb7073ed7858d3424ccf774e5f6a946bec59Vasu Nori
5496baceb7073ed7858d3424ccf774e5f6a946bec59Vasu Nori    void startDownloadThread() {
5506baceb7073ed7858d3424ccf774e5f6a946bec59Vasu Nori        DownloadThread downloader = new DownloadThread(mContext, mSystemFacade, this,
5516baceb7073ed7858d3424ccf774e5f6a946bec59Vasu Nori                StorageManager.getInstance(mContext));
5526baceb7073ed7858d3424ccf774e5f6a946bec59Vasu Nori        mSystemFacade.startThread(downloader);
5536baceb7073ed7858d3424ccf774e5f6a946bec59Vasu Nori    }
55457f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project}
555