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