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 376da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkeyimport com.android.internal.util.IndentingPrintWriter; 386da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey 39ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howardimport java.util.ArrayList; 40ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howardimport java.util.Collection; 415224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howardimport java.util.Collections; 42ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howardimport java.util.List; 435224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howard 4457f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project/** 4557f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project * Stores information about an individual download. 4657f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project */ 4757f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Projectpublic class DownloadInfo { 483398db8f3b195959faa2a7cf09918f364432ac28Steve Howard public static class Reader { 493398db8f3b195959faa2a7cf09918f364432ac28Steve Howard private ContentResolver mResolver; 503398db8f3b195959faa2a7cf09918f364432ac28Steve Howard private Cursor mCursor; 513398db8f3b195959faa2a7cf09918f364432ac28Steve Howard 523398db8f3b195959faa2a7cf09918f364432ac28Steve Howard public Reader(ContentResolver resolver, Cursor cursor) { 533398db8f3b195959faa2a7cf09918f364432ac28Steve Howard mResolver = resolver; 543398db8f3b195959faa2a7cf09918f364432ac28Steve Howard mCursor = cursor; 553398db8f3b195959faa2a7cf09918f364432ac28Steve Howard } 563398db8f3b195959faa2a7cf09918f364432ac28Steve Howard 573398db8f3b195959faa2a7cf09918f364432ac28Steve Howard public DownloadInfo newDownloadInfo(Context context, SystemFacade systemFacade) { 583398db8f3b195959faa2a7cf09918f364432ac28Steve Howard DownloadInfo info = new DownloadInfo(context, systemFacade); 593398db8f3b195959faa2a7cf09918f364432ac28Steve Howard updateFromDatabase(info); 603398db8f3b195959faa2a7cf09918f364432ac28Steve Howard readRequestHeaders(info); 613398db8f3b195959faa2a7cf09918f364432ac28Steve Howard return info; 623398db8f3b195959faa2a7cf09918f364432ac28Steve Howard } 633398db8f3b195959faa2a7cf09918f364432ac28Steve Howard 643398db8f3b195959faa2a7cf09918f364432ac28Steve Howard public void updateFromDatabase(DownloadInfo info) { 653398db8f3b195959faa2a7cf09918f364432ac28Steve Howard info.mId = getLong(Downloads.Impl._ID); 661dc416983a4638a250b67b11564466088cfa41f6Vasu Nori info.mUri = getString(Downloads.Impl.COLUMN_URI); 673398db8f3b195959faa2a7cf09918f364432ac28Steve Howard info.mNoIntegrity = getInt(Downloads.Impl.COLUMN_NO_INTEGRITY) == 1; 681dc416983a4638a250b67b11564466088cfa41f6Vasu Nori info.mHint = getString(Downloads.Impl.COLUMN_FILE_NAME_HINT); 691dc416983a4638a250b67b11564466088cfa41f6Vasu Nori info.mFileName = getString(Downloads.Impl._DATA); 701dc416983a4638a250b67b11564466088cfa41f6Vasu Nori info.mMimeType = getString(Downloads.Impl.COLUMN_MIME_TYPE); 713398db8f3b195959faa2a7cf09918f364432ac28Steve Howard info.mDestination = getInt(Downloads.Impl.COLUMN_DESTINATION); 723398db8f3b195959faa2a7cf09918f364432ac28Steve Howard info.mVisibility = getInt(Downloads.Impl.COLUMN_VISIBILITY); 733398db8f3b195959faa2a7cf09918f364432ac28Steve Howard info.mStatus = getInt(Downloads.Impl.COLUMN_STATUS); 743398db8f3b195959faa2a7cf09918f364432ac28Steve Howard info.mNumFailed = getInt(Constants.FAILED_CONNECTIONS); 753398db8f3b195959faa2a7cf09918f364432ac28Steve Howard int retryRedirect = getInt(Constants.RETRY_AFTER_X_REDIRECT_COUNT); 763398db8f3b195959faa2a7cf09918f364432ac28Steve Howard info.mRetryAfter = retryRedirect & 0xfffffff; 773398db8f3b195959faa2a7cf09918f364432ac28Steve Howard info.mLastMod = getLong(Downloads.Impl.COLUMN_LAST_MODIFICATION); 781dc416983a4638a250b67b11564466088cfa41f6Vasu Nori info.mPackage = getString(Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE); 791dc416983a4638a250b67b11564466088cfa41f6Vasu Nori info.mClass = getString(Downloads.Impl.COLUMN_NOTIFICATION_CLASS); 801dc416983a4638a250b67b11564466088cfa41f6Vasu Nori info.mExtras = getString(Downloads.Impl.COLUMN_NOTIFICATION_EXTRAS); 811dc416983a4638a250b67b11564466088cfa41f6Vasu Nori info.mCookies = getString(Downloads.Impl.COLUMN_COOKIE_DATA); 821dc416983a4638a250b67b11564466088cfa41f6Vasu Nori info.mUserAgent = getString(Downloads.Impl.COLUMN_USER_AGENT); 831dc416983a4638a250b67b11564466088cfa41f6Vasu Nori info.mReferer = getString(Downloads.Impl.COLUMN_REFERER); 843398db8f3b195959faa2a7cf09918f364432ac28Steve Howard info.mTotalBytes = getLong(Downloads.Impl.COLUMN_TOTAL_BYTES); 853398db8f3b195959faa2a7cf09918f364432ac28Steve Howard info.mCurrentBytes = getLong(Downloads.Impl.COLUMN_CURRENT_BYTES); 861dc416983a4638a250b67b11564466088cfa41f6Vasu Nori info.mETag = getString(Constants.ETAG); 87665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey info.mUid = getInt(Constants.UID); 88b18ed519040c1ecd98f8cb139adcc315a3f4eedcVasu Nori info.mMediaScanned = getInt(Constants.MEDIA_SCANNED); 89e00c31208405bd2e4c88e069df7a2b15237f70bfVasu Nori info.mDeleted = getInt(Downloads.Impl.COLUMN_DELETED) == 1; 901dc416983a4638a250b67b11564466088cfa41f6Vasu Nori info.mMediaProviderUri = getString(Downloads.Impl.COLUMN_MEDIAPROVIDER_URI); 913398db8f3b195959faa2a7cf09918f364432ac28Steve Howard info.mIsPublicApi = getInt(Downloads.Impl.COLUMN_IS_PUBLIC_API) != 0; 923398db8f3b195959faa2a7cf09918f364432ac28Steve Howard info.mAllowedNetworkTypes = getInt(Downloads.Impl.COLUMN_ALLOWED_NETWORK_TYPES); 933398db8f3b195959faa2a7cf09918f364432ac28Steve Howard info.mAllowRoaming = getInt(Downloads.Impl.COLUMN_ALLOW_ROAMING) != 0; 94a7ae77fdae69bcc6d6609d4639fed5d96e55eeaaJeff Sharkey info.mAllowMetered = getInt(Downloads.Impl.COLUMN_ALLOW_METERED) != 0; 951dc416983a4638a250b67b11564466088cfa41f6Vasu Nori info.mTitle = getString(Downloads.Impl.COLUMN_TITLE); 961dc416983a4638a250b67b11564466088cfa41f6Vasu Nori info.mDescription = getString(Downloads.Impl.COLUMN_DESCRIPTION); 97d319729622da1893e895f2e35f41d01ecdca3705Steve Howard info.mBypassRecommendedSizeLimit = 98d319729622da1893e895f2e35f41d01ecdca3705Steve Howard getInt(Downloads.Impl.COLUMN_BYPASS_RECOMMENDED_SIZE_LIMIT); 993398db8f3b195959faa2a7cf09918f364432ac28Steve Howard 1003398db8f3b195959faa2a7cf09918f364432ac28Steve Howard synchronized (this) { 1013398db8f3b195959faa2a7cf09918f364432ac28Steve Howard info.mControl = getInt(Downloads.Impl.COLUMN_CONTROL); 1023398db8f3b195959faa2a7cf09918f364432ac28Steve Howard } 1033398db8f3b195959faa2a7cf09918f364432ac28Steve Howard } 1043398db8f3b195959faa2a7cf09918f364432ac28Steve Howard 1053398db8f3b195959faa2a7cf09918f364432ac28Steve Howard private void readRequestHeaders(DownloadInfo info) { 1063398db8f3b195959faa2a7cf09918f364432ac28Steve Howard info.mRequestHeaders.clear(); 1073398db8f3b195959faa2a7cf09918f364432ac28Steve Howard Uri headerUri = Uri.withAppendedPath( 1083398db8f3b195959faa2a7cf09918f364432ac28Steve Howard info.getAllDownloadsUri(), Downloads.Impl.RequestHeaders.URI_SEGMENT); 1093398db8f3b195959faa2a7cf09918f364432ac28Steve Howard Cursor cursor = mResolver.query(headerUri, null, null, null, null); 1103398db8f3b195959faa2a7cf09918f364432ac28Steve Howard try { 1113398db8f3b195959faa2a7cf09918f364432ac28Steve Howard int headerIndex = 1123398db8f3b195959faa2a7cf09918f364432ac28Steve Howard cursor.getColumnIndexOrThrow(Downloads.Impl.RequestHeaders.COLUMN_HEADER); 1133398db8f3b195959faa2a7cf09918f364432ac28Steve Howard int valueIndex = 1143398db8f3b195959faa2a7cf09918f364432ac28Steve Howard cursor.getColumnIndexOrThrow(Downloads.Impl.RequestHeaders.COLUMN_VALUE); 1153398db8f3b195959faa2a7cf09918f364432ac28Steve Howard for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { 116ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard addHeader(info, cursor.getString(headerIndex), cursor.getString(valueIndex)); 1173398db8f3b195959faa2a7cf09918f364432ac28Steve Howard } 1183398db8f3b195959faa2a7cf09918f364432ac28Steve Howard } finally { 1193398db8f3b195959faa2a7cf09918f364432ac28Steve Howard cursor.close(); 1203398db8f3b195959faa2a7cf09918f364432ac28Steve Howard } 1213398db8f3b195959faa2a7cf09918f364432ac28Steve Howard 1223398db8f3b195959faa2a7cf09918f364432ac28Steve Howard if (info.mCookies != null) { 123ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard addHeader(info, "Cookie", info.mCookies); 1243398db8f3b195959faa2a7cf09918f364432ac28Steve Howard } 1253398db8f3b195959faa2a7cf09918f364432ac28Steve Howard if (info.mReferer != null) { 126ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard addHeader(info, "Referer", info.mReferer); 1273398db8f3b195959faa2a7cf09918f364432ac28Steve Howard } 1283398db8f3b195959faa2a7cf09918f364432ac28Steve Howard } 1293398db8f3b195959faa2a7cf09918f364432ac28Steve Howard 130ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard private void addHeader(DownloadInfo info, String header, String value) { 131ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard info.mRequestHeaders.add(Pair.create(header, value)); 132ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard } 133ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard 1341dc416983a4638a250b67b11564466088cfa41f6Vasu Nori private String getString(String column) { 1353398db8f3b195959faa2a7cf09918f364432ac28Steve Howard int index = mCursor.getColumnIndexOrThrow(column); 1361dc416983a4638a250b67b11564466088cfa41f6Vasu Nori String s = mCursor.getString(index); 1371dc416983a4638a250b67b11564466088cfa41f6Vasu Nori return (TextUtils.isEmpty(s)) ? null : s; 1383398db8f3b195959faa2a7cf09918f364432ac28Steve Howard } 1393398db8f3b195959faa2a7cf09918f364432ac28Steve Howard 1403398db8f3b195959faa2a7cf09918f364432ac28Steve Howard private Integer getInt(String column) { 1413398db8f3b195959faa2a7cf09918f364432ac28Steve Howard return mCursor.getInt(mCursor.getColumnIndexOrThrow(column)); 1423398db8f3b195959faa2a7cf09918f364432ac28Steve Howard } 1433398db8f3b195959faa2a7cf09918f364432ac28Steve Howard 1443398db8f3b195959faa2a7cf09918f364432ac28Steve Howard private Long getLong(String column) { 1453398db8f3b195959faa2a7cf09918f364432ac28Steve Howard return mCursor.getLong(mCursor.getColumnIndexOrThrow(column)); 1463398db8f3b195959faa2a7cf09918f364432ac28Steve Howard } 1473398db8f3b195959faa2a7cf09918f364432ac28Steve Howard } 1483398db8f3b195959faa2a7cf09918f364432ac28Steve Howard 149d319729622da1893e895f2e35f41d01ecdca3705Steve Howard // the following NETWORK_* constants are used to indicates specfic reasons for disallowing a 150d319729622da1893e895f2e35f41d01ecdca3705Steve Howard // download from using a network, since specific causes can require special handling 151d319729622da1893e895f2e35f41d01ecdca3705Steve Howard 152d319729622da1893e895f2e35f41d01ecdca3705Steve Howard /** 153d319729622da1893e895f2e35f41d01ecdca3705Steve Howard * The network is usable for the given download. 154d319729622da1893e895f2e35f41d01ecdca3705Steve Howard */ 155d319729622da1893e895f2e35f41d01ecdca3705Steve Howard public static final int NETWORK_OK = 1; 156d319729622da1893e895f2e35f41d01ecdca3705Steve Howard 157d319729622da1893e895f2e35f41d01ecdca3705Steve Howard /** 15826604ffc248081b8014ff7260536d18b43cb0de9Steve Howard * There is no network connectivity. 159d319729622da1893e895f2e35f41d01ecdca3705Steve Howard */ 16026604ffc248081b8014ff7260536d18b43cb0de9Steve Howard public static final int NETWORK_NO_CONNECTION = 2; 161d319729622da1893e895f2e35f41d01ecdca3705Steve Howard 162d319729622da1893e895f2e35f41d01ecdca3705Steve Howard /** 163d319729622da1893e895f2e35f41d01ecdca3705Steve Howard * The download exceeds the maximum size for this network. 164d319729622da1893e895f2e35f41d01ecdca3705Steve Howard */ 165d319729622da1893e895f2e35f41d01ecdca3705Steve Howard public static final int NETWORK_UNUSABLE_DUE_TO_SIZE = 3; 166d319729622da1893e895f2e35f41d01ecdca3705Steve Howard 167d319729622da1893e895f2e35f41d01ecdca3705Steve Howard /** 168d319729622da1893e895f2e35f41d01ecdca3705Steve Howard * The download exceeds the recommended maximum size for this network, the user must confirm for 169d319729622da1893e895f2e35f41d01ecdca3705Steve Howard * this download to proceed without WiFi. 170d319729622da1893e895f2e35f41d01ecdca3705Steve Howard */ 171d319729622da1893e895f2e35f41d01ecdca3705Steve Howard public static final int NETWORK_RECOMMENDED_UNUSABLE_DUE_TO_SIZE = 4; 172d319729622da1893e895f2e35f41d01ecdca3705Steve Howard 173d319729622da1893e895f2e35f41d01ecdca3705Steve Howard /** 17426604ffc248081b8014ff7260536d18b43cb0de9Steve Howard * The current connection is roaming, and the download can't proceed over a roaming connection. 17526604ffc248081b8014ff7260536d18b43cb0de9Steve Howard */ 17626604ffc248081b8014ff7260536d18b43cb0de9Steve Howard public static final int NETWORK_CANNOT_USE_ROAMING = 5; 17726604ffc248081b8014ff7260536d18b43cb0de9Steve Howard 17826604ffc248081b8014ff7260536d18b43cb0de9Steve Howard /** 17926604ffc248081b8014ff7260536d18b43cb0de9Steve Howard * The app requesting the download specific that it can't use the current network connection. 18026604ffc248081b8014ff7260536d18b43cb0de9Steve Howard */ 18126604ffc248081b8014ff7260536d18b43cb0de9Steve Howard public static final int NETWORK_TYPE_DISALLOWED_BY_REQUESTOR = 6; 18226604ffc248081b8014ff7260536d18b43cb0de9Steve Howard 18326604ffc248081b8014ff7260536d18b43cb0de9Steve Howard /** 184961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey * Current network is blocked for requesting application. 185961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey */ 186961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey public static final int NETWORK_BLOCKED = 7; 187961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey 188961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey /** 189d319729622da1893e895f2e35f41d01ecdca3705Steve Howard * For intents used to notify the user that a download exceeds a size threshold, if this extra 190d319729622da1893e895f2e35f41d01ecdca3705Steve Howard * is true, WiFi is required for this download size; otherwise, it is only recommended. 191d319729622da1893e895f2e35f41d01ecdca3705Steve Howard */ 192d319729622da1893e895f2e35f41d01ecdca3705Steve Howard public static final String EXTRA_IS_WIFI_REQUIRED = "isWifiRequired"; 193d319729622da1893e895f2e35f41d01ecdca3705Steve Howard 194d319729622da1893e895f2e35f41d01ecdca3705Steve Howard 1953398db8f3b195959faa2a7cf09918f364432ac28Steve Howard public long mId; 196c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru public String mUri; 197c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru public boolean mNoIntegrity; 198c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru public String mHint; 199c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru public String mFileName; 200c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru public String mMimeType; 201c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru public int mDestination; 202c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru public int mVisibility; 203c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru public int mControl; 204c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru public int mStatus; 205c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru public int mNumFailed; 206c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru public int mRetryAfter; 207c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru public long mLastMod; 208c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru public String mPackage; 209c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru public String mClass; 210c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru public String mExtras; 211c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru public String mCookies; 212c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru public String mUserAgent; 213c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru public String mReferer; 214b5629da794cb3c1ca1970d206343743b165b9644Steve Howard public long mTotalBytes; 215b5629da794cb3c1ca1970d206343743b165b9644Steve Howard public long mCurrentBytes; 216c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru public String mETag; 217665f4105ea68a05d85dcd22cc9d823f45f7e6a37Jeff Sharkey public int mUid; 218b18ed519040c1ecd98f8cb139adcc315a3f4eedcVasu Nori public int mMediaScanned; 219e00c31208405bd2e4c88e069df7a2b15237f70bfVasu Nori public boolean mDeleted; 220e00c31208405bd2e4c88e069df7a2b15237f70bfVasu Nori public String mMediaProviderUri; 2210a77c62a82503b38c484e0079648f0231dd85d53Steve Howard public boolean mIsPublicApi; 2220a77c62a82503b38c484e0079648f0231dd85d53Steve Howard public int mAllowedNetworkTypes; 2230a77c62a82503b38c484e0079648f0231dd85d53Steve Howard public boolean mAllowRoaming; 224a7ae77fdae69bcc6d6609d4639fed5d96e55eeaaJeff Sharkey public boolean mAllowMetered; 22597d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard public String mTitle; 22697d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard public String mDescription; 227d319729622da1893e895f2e35f41d01ecdca3705Steve Howard public int mBypassRecommendedSizeLimit; 22857f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project 2294a977a52c3eb3ac08b94b81aef72fb618be39f81Jean-Baptiste Queru public int mFuzz; 2304a977a52c3eb3ac08b94b81aef72fb618be39f81Jean-Baptiste Queru 231ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard private List<Pair<String, String>> mRequestHeaders = new ArrayList<Pair<String, String>>(); 232071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard private SystemFacade mSystemFacade; 233071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard private Context mContext; 234071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard 2353398db8f3b195959faa2a7cf09918f364432ac28Steve Howard private DownloadInfo(Context context, SystemFacade systemFacade) { 236071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard mContext = context; 237071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard mSystemFacade = systemFacade; 2385224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howard mFuzz = Helpers.sRandom.nextInt(1001); 2395224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howard } 24057f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project 241ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard public Collection<Pair<String, String>> getHeaders() { 242ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard return Collections.unmodifiableList(mRequestHeaders); 24357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } 24457f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project 2453d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard public void sendIntentIfRequested() { 2460a77c62a82503b38c484e0079648f0231dd85d53Steve Howard if (mPackage == null) { 2470a77c62a82503b38c484e0079648f0231dd85d53Steve Howard return; 2480a77c62a82503b38c484e0079648f0231dd85d53Steve Howard } 2490a77c62a82503b38c484e0079648f0231dd85d53Steve Howard 2500a77c62a82503b38c484e0079648f0231dd85d53Steve Howard Intent intent; 2510a77c62a82503b38c484e0079648f0231dd85d53Steve Howard if (mIsPublicApi) { 2520a77c62a82503b38c484e0079648f0231dd85d53Steve Howard intent = new Intent(DownloadManager.ACTION_DOWNLOAD_COMPLETE); 2530a77c62a82503b38c484e0079648f0231dd85d53Steve Howard intent.setPackage(mPackage); 2543398db8f3b195959faa2a7cf09918f364432ac28Steve Howard intent.putExtra(DownloadManager.EXTRA_DOWNLOAD_ID, mId); 2550a77c62a82503b38c484e0079648f0231dd85d53Steve Howard } else { // legacy behavior 2560a77c62a82503b38c484e0079648f0231dd85d53Steve Howard if (mClass == null) { 2570a77c62a82503b38c484e0079648f0231dd85d53Steve Howard return; 2580a77c62a82503b38c484e0079648f0231dd85d53Steve Howard } 2590a77c62a82503b38c484e0079648f0231dd85d53Steve Howard intent = new Intent(Downloads.Impl.ACTION_DOWNLOAD_COMPLETED); 260c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru intent.setClassName(mPackage, mClass); 261c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru if (mExtras != null) { 2627dd92fa94df0a13b4592ee636b7aa2b605f6b473Jean-Baptiste Queru intent.putExtra(Downloads.Impl.COLUMN_NOTIFICATION_EXTRAS, mExtras); 26357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } 26457f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project // We only send the content: URI, for security reasons. Otherwise, malicious 26557f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project // applications would have an easier time spoofing download results by 26657f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project // sending spoofed intents. 2673d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard intent.setData(getMyDownloadsUri()); 26857f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } 2690a77c62a82503b38c484e0079648f0231dd85d53Steve Howard mSystemFacade.sendBroadcast(intent); 27057f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } 27157f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project 27257f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project /** 273b108a273b150e81bf26553b8851d6241bc711f98Steve Howard * Returns the time when a download should be restarted. 27457f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project */ 275b108a273b150e81bf26553b8851d6241bc711f98Steve Howard public long restartTime(long now) { 276b108a273b150e81bf26553b8851d6241bc711f98Steve Howard if (mNumFailed == 0) { 277b108a273b150e81bf26553b8851d6241bc711f98Steve Howard return now; 278b108a273b150e81bf26553b8851d6241bc711f98Steve Howard } 279c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru if (mRetryAfter > 0) { 280c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru return mLastMod + mRetryAfter; 2811fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project } 282c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru return mLastMod + 2831fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project Constants.RETRY_FIRST_DELAY * 2844a977a52c3eb3ac08b94b81aef72fb618be39f81Jean-Baptiste Queru (1000 + mFuzz) * (1 << (mNumFailed - 1)); 28557f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } 28657f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project 28757f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project /** 2881fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project * Returns whether this download (which the download manager hasn't seen yet) 2891fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project * should be started. 29057f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project */ 291b108a273b150e81bf26553b8851d6241bc711f98Steve Howard private boolean isReadyToStart(long now) { 2926baceb7073ed7858d3424ccf774e5f6a946bec59Vasu Nori if (DownloadHandler.getInstance().hasDownloadInQueue(mId)) { 293b108a273b150e81bf26553b8851d6241bc711f98Steve Howard // already running 294b108a273b150e81bf26553b8851d6241bc711f98Steve Howard return false; 295b108a273b150e81bf26553b8851d6241bc711f98Steve Howard } 2967dd92fa94df0a13b4592ee636b7aa2b605f6b473Jean-Baptiste Queru if (mControl == Downloads.Impl.CONTROL_PAUSED) { 2971fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project // the download is paused, so it's not going to start 2981fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project return false; 2991fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project } 300b108a273b150e81bf26553b8851d6241bc711f98Steve Howard switch (mStatus) { 301b108a273b150e81bf26553b8851d6241bc711f98Steve Howard case 0: // status hasn't been initialized yet, this is a new download 302b108a273b150e81bf26553b8851d6241bc711f98Steve Howard case Downloads.Impl.STATUS_PENDING: // download is explicit marked as ready to start 303b108a273b150e81bf26553b8851d6241bc711f98Steve Howard case Downloads.Impl.STATUS_RUNNING: // download interrupted (process killed etc) while 304b108a273b150e81bf26553b8851d6241bc711f98Steve Howard // running, without a chance to update the database 30557f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project return true; 30657f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project 307b108a273b150e81bf26553b8851d6241bc711f98Steve Howard case Downloads.Impl.STATUS_WAITING_FOR_NETWORK: 308b108a273b150e81bf26553b8851d6241bc711f98Steve Howard case Downloads.Impl.STATUS_QUEUED_FOR_WIFI: 309d319729622da1893e895f2e35f41d01ecdca3705Steve Howard return checkCanUseNetwork() == NETWORK_OK; 310b108a273b150e81bf26553b8851d6241bc711f98Steve Howard 311b108a273b150e81bf26553b8851d6241bc711f98Steve Howard case Downloads.Impl.STATUS_WAITING_TO_RETRY: 312b108a273b150e81bf26553b8851d6241bc711f98Steve Howard // download was waiting for a delayed restart 313b108a273b150e81bf26553b8851d6241bc711f98Steve Howard return restartTime(now) <= now; 314789745f667c65661d82ccbd5ef49fdb132911736Vasu Nori case Downloads.Impl.STATUS_DEVICE_NOT_FOUND_ERROR: 315789745f667c65661d82ccbd5ef49fdb132911736Vasu Nori // is the media mounted? 316789745f667c65661d82ccbd5ef49fdb132911736Vasu Nori return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED); 317789745f667c65661d82ccbd5ef49fdb132911736Vasu Nori case Downloads.Impl.STATUS_INSUFFICIENT_SPACE_ERROR: 318579be0d0d0de6af307ee94af07720a568ed2e7d1Hideki Hayami // avoids repetition of retrying download 319579be0d0d0de6af307ee94af07720a568ed2e7d1Hideki Hayami return false; 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); 344b92aa3a88dd25a798bbedc860d9b29aef42bbb0fJeff Sharkey if (info == null || !info.isConnected()) { 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 } 353a7ae77fdae69bcc6d6609d4639fed5d96e55eeaaJeff Sharkey if (!mAllowMetered && mSystemFacade.isActiveNetworkMetered()) { 354a7ae77fdae69bcc6d6609d4639fed5d96e55eeaaJeff Sharkey return NETWORK_TYPE_DISALLOWED_BY_REQUESTOR; 355a7ae77fdae69bcc6d6609d4639fed5d96e55eeaaJeff Sharkey } 356961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey return checkIsNetworkTypeAllowed(info.getType()); 357071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard } 358071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard 3590a77c62a82503b38c484e0079648f0231dd85d53Steve Howard private boolean isRoamingAllowed() { 3600a77c62a82503b38c484e0079648f0231dd85d53Steve Howard if (mIsPublicApi) { 3610a77c62a82503b38c484e0079648f0231dd85d53Steve Howard return mAllowRoaming; 3620a77c62a82503b38c484e0079648f0231dd85d53Steve Howard } else { // legacy behavior 3630a77c62a82503b38c484e0079648f0231dd85d53Steve Howard return mDestination != Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING; 3640a77c62a82503b38c484e0079648f0231dd85d53Steve Howard } 3650a77c62a82503b38c484e0079648f0231dd85d53Steve Howard } 3660a77c62a82503b38c484e0079648f0231dd85d53Steve Howard 3670a77c62a82503b38c484e0079648f0231dd85d53Steve Howard /** 36826604ffc248081b8014ff7260536d18b43cb0de9Steve Howard * @return a non-localized string appropriate for logging corresponding to one of the 36926604ffc248081b8014ff7260536d18b43cb0de9Steve Howard * NETWORK_* constants. 37026604ffc248081b8014ff7260536d18b43cb0de9Steve Howard */ 37126604ffc248081b8014ff7260536d18b43cb0de9Steve Howard public String getLogMessageForNetworkError(int networkError) { 37226604ffc248081b8014ff7260536d18b43cb0de9Steve Howard switch (networkError) { 37326604ffc248081b8014ff7260536d18b43cb0de9Steve Howard case NETWORK_RECOMMENDED_UNUSABLE_DUE_TO_SIZE: 37426604ffc248081b8014ff7260536d18b43cb0de9Steve Howard return "download size exceeds recommended limit for mobile network"; 37526604ffc248081b8014ff7260536d18b43cb0de9Steve Howard 37626604ffc248081b8014ff7260536d18b43cb0de9Steve Howard case NETWORK_UNUSABLE_DUE_TO_SIZE: 37726604ffc248081b8014ff7260536d18b43cb0de9Steve Howard return "download size exceeds limit for mobile network"; 37826604ffc248081b8014ff7260536d18b43cb0de9Steve Howard 37926604ffc248081b8014ff7260536d18b43cb0de9Steve Howard case NETWORK_NO_CONNECTION: 38026604ffc248081b8014ff7260536d18b43cb0de9Steve Howard return "no network connection available"; 38126604ffc248081b8014ff7260536d18b43cb0de9Steve Howard 38226604ffc248081b8014ff7260536d18b43cb0de9Steve Howard case NETWORK_CANNOT_USE_ROAMING: 38326604ffc248081b8014ff7260536d18b43cb0de9Steve Howard return "download cannot use the current network connection because it is roaming"; 38426604ffc248081b8014ff7260536d18b43cb0de9Steve Howard 38526604ffc248081b8014ff7260536d18b43cb0de9Steve Howard case NETWORK_TYPE_DISALLOWED_BY_REQUESTOR: 38626604ffc248081b8014ff7260536d18b43cb0de9Steve Howard return "download was requested to not use the current network type"; 38726604ffc248081b8014ff7260536d18b43cb0de9Steve Howard 388961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey case NETWORK_BLOCKED: 389961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey return "network is blocked for requesting application"; 390961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey 39126604ffc248081b8014ff7260536d18b43cb0de9Steve Howard default: 39226604ffc248081b8014ff7260536d18b43cb0de9Steve Howard return "unknown error with network connectivity"; 39326604ffc248081b8014ff7260536d18b43cb0de9Steve Howard } 39426604ffc248081b8014ff7260536d18b43cb0de9Steve Howard } 39526604ffc248081b8014ff7260536d18b43cb0de9Steve Howard 39626604ffc248081b8014ff7260536d18b43cb0de9Steve Howard /** 3970a77c62a82503b38c484e0079648f0231dd85d53Steve Howard * Check if this download can proceed over the given network type. 3980a77c62a82503b38c484e0079648f0231dd85d53Steve Howard * @param networkType a constant from ConnectivityManager.TYPE_*. 399d319729622da1893e895f2e35f41d01ecdca3705Steve Howard * @return one of the NETWORK_* constants 4000a77c62a82503b38c484e0079648f0231dd85d53Steve Howard */ 401d319729622da1893e895f2e35f41d01ecdca3705Steve Howard private int checkIsNetworkTypeAllowed(int networkType) { 4020a77c62a82503b38c484e0079648f0231dd85d53Steve Howard if (mIsPublicApi) { 403f720bc684b1a8332eb4d5f8d25c5feaf7eb54433Jeff Sharkey final int flag = translateNetworkTypeToApiFlag(networkType); 404f720bc684b1a8332eb4d5f8d25c5feaf7eb54433Jeff Sharkey final boolean allowAllNetworkTypes = mAllowedNetworkTypes == ~0; 405f720bc684b1a8332eb4d5f8d25c5feaf7eb54433Jeff Sharkey if (!allowAllNetworkTypes && (flag & mAllowedNetworkTypes) == 0) { 40626604ffc248081b8014ff7260536d18b43cb0de9Steve Howard return NETWORK_TYPE_DISALLOWED_BY_REQUESTOR; 4070a77c62a82503b38c484e0079648f0231dd85d53Steve Howard } 4080a77c62a82503b38c484e0079648f0231dd85d53Steve Howard } 409d319729622da1893e895f2e35f41d01ecdca3705Steve Howard return checkSizeAllowedForNetwork(networkType); 4100a77c62a82503b38c484e0079648f0231dd85d53Steve Howard } 4110a77c62a82503b38c484e0079648f0231dd85d53Steve Howard 4120a77c62a82503b38c484e0079648f0231dd85d53Steve Howard /** 4130a77c62a82503b38c484e0079648f0231dd85d53Steve Howard * Translate a ConnectivityManager.TYPE_* constant to the corresponding 4140a77c62a82503b38c484e0079648f0231dd85d53Steve Howard * DownloadManager.Request.NETWORK_* bit flag. 4150a77c62a82503b38c484e0079648f0231dd85d53Steve Howard */ 4160a77c62a82503b38c484e0079648f0231dd85d53Steve Howard private int translateNetworkTypeToApiFlag(int networkType) { 4170a77c62a82503b38c484e0079648f0231dd85d53Steve Howard switch (networkType) { 4180a77c62a82503b38c484e0079648f0231dd85d53Steve Howard case ConnectivityManager.TYPE_MOBILE: 4190a77c62a82503b38c484e0079648f0231dd85d53Steve Howard return DownloadManager.Request.NETWORK_MOBILE; 4200a77c62a82503b38c484e0079648f0231dd85d53Steve Howard 4210a77c62a82503b38c484e0079648f0231dd85d53Steve Howard case ConnectivityManager.TYPE_WIFI: 4220a77c62a82503b38c484e0079648f0231dd85d53Steve Howard return DownloadManager.Request.NETWORK_WIFI; 4230a77c62a82503b38c484e0079648f0231dd85d53Steve Howard 42461dc320aa883a2fcf68d44ef0bbe4cd7c51a7655HÃ¥kan case ConnectivityManager.TYPE_BLUETOOTH: 42561dc320aa883a2fcf68d44ef0bbe4cd7c51a7655HÃ¥kan return DownloadManager.Request.NETWORK_BLUETOOTH; 42661dc320aa883a2fcf68d44ef0bbe4cd7c51a7655HÃ¥kan 4270a77c62a82503b38c484e0079648f0231dd85d53Steve Howard default: 4280a77c62a82503b38c484e0079648f0231dd85d53Steve Howard return 0; 4290a77c62a82503b38c484e0079648f0231dd85d53Steve Howard } 4300a77c62a82503b38c484e0079648f0231dd85d53Steve Howard } 4310a77c62a82503b38c484e0079648f0231dd85d53Steve Howard 432071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard /** 433071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard * Check if the download's size prohibits it from running over the current network. 434d319729622da1893e895f2e35f41d01ecdca3705Steve Howard * @return one of the NETWORK_* constants 435071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard */ 436d319729622da1893e895f2e35f41d01ecdca3705Steve Howard private int checkSizeAllowedForNetwork(int networkType) { 437071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard if (mTotalBytes <= 0) { 438d319729622da1893e895f2e35f41d01ecdca3705Steve Howard return NETWORK_OK; // we don't know the size yet 439071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard } 440071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard if (networkType == ConnectivityManager.TYPE_WIFI) { 441d319729622da1893e895f2e35f41d01ecdca3705Steve Howard return NETWORK_OK; // anything goes over wifi 442071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard } 4430d4f9f105c3a31475a36e9a1edfa868c66ff455fSteve Howard Long maxBytesOverMobile = mSystemFacade.getMaxBytesOverMobile(); 444d319729622da1893e895f2e35f41d01ecdca3705Steve Howard if (maxBytesOverMobile != null && mTotalBytes > maxBytesOverMobile) { 445d319729622da1893e895f2e35f41d01ecdca3705Steve Howard return NETWORK_UNUSABLE_DUE_TO_SIZE; 446d319729622da1893e895f2e35f41d01ecdca3705Steve Howard } 447d319729622da1893e895f2e35f41d01ecdca3705Steve Howard if (mBypassRecommendedSizeLimit == 0) { 448d319729622da1893e895f2e35f41d01ecdca3705Steve Howard Long recommendedMaxBytesOverMobile = mSystemFacade.getRecommendedMaxBytesOverMobile(); 449d319729622da1893e895f2e35f41d01ecdca3705Steve Howard if (recommendedMaxBytesOverMobile != null 450d319729622da1893e895f2e35f41d01ecdca3705Steve Howard && mTotalBytes > recommendedMaxBytesOverMobile) { 451d319729622da1893e895f2e35f41d01ecdca3705Steve Howard return NETWORK_RECOMMENDED_UNUSABLE_DUE_TO_SIZE; 452d319729622da1893e895f2e35f41d01ecdca3705Steve Howard } 453071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard } 454d319729622da1893e895f2e35f41d01ecdca3705Steve Howard return NETWORK_OK; 455071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard } 456071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard 4575218d33d57990c3e3549c58bd3f0ac244dfc3d59Vasu Nori void startIfReady(long now, StorageManager storageManager) { 458b108a273b150e81bf26553b8851d6241bc711f98Steve Howard if (!isReadyToStart(now)) { 459b108a273b150e81bf26553b8851d6241bc711f98Steve Howard return; 460b108a273b150e81bf26553b8851d6241bc711f98Steve Howard } 461b108a273b150e81bf26553b8851d6241bc711f98Steve Howard 4625180de23e77139dd6971dfd48269242e3e3562d9Steve Howard if (Constants.LOGV) { 4635180de23e77139dd6971dfd48269242e3e3562d9Steve Howard Log.v(Constants.TAG, "Service spawning thread to handle download " + mId); 4645180de23e77139dd6971dfd48269242e3e3562d9Steve Howard } 4655180de23e77139dd6971dfd48269242e3e3562d9Steve Howard if (mStatus != Impl.STATUS_RUNNING) { 4665180de23e77139dd6971dfd48269242e3e3562d9Steve Howard mStatus = Impl.STATUS_RUNNING; 4675180de23e77139dd6971dfd48269242e3e3562d9Steve Howard ContentValues values = new ContentValues(); 4685180de23e77139dd6971dfd48269242e3e3562d9Steve Howard values.put(Impl.COLUMN_STATUS, mStatus); 4693d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard mContext.getContentResolver().update(getAllDownloadsUri(), values, null, null); 4701fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project } 4716baceb7073ed7858d3424ccf774e5f6a946bec59Vasu Nori DownloadHandler.getInstance().enqueueDownload(this); 4721fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project } 473adb6887d3270d180c94eaf90878d5b67d74a8f28Steve Howard 474adb6887d3270d180c94eaf90878d5b67d74a8f28Steve Howard public boolean isOnCache() { 475adb6887d3270d180c94eaf90878d5b67d74a8f28Steve Howard return (mDestination == Downloads.Impl.DESTINATION_CACHE_PARTITION 4769aadb4b3f2b3c914166ebfae8851fbecaf536f4fVasu Nori || mDestination == Downloads.Impl.DESTINATION_SYSTEMCACHE_PARTITION 477adb6887d3270d180c94eaf90878d5b67d74a8f28Steve Howard || mDestination == Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING 478adb6887d3270d180c94eaf90878d5b67d74a8f28Steve Howard || mDestination == Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE); 479adb6887d3270d180c94eaf90878d5b67d74a8f28Steve Howard } 4803d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard 4813d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard public Uri getMyDownloadsUri() { 4823d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard return ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, mId); 4833d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard } 4843d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard 4853d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard public Uri getAllDownloadsUri() { 4863d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard return ContentUris.withAppendedId(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, mId); 4873d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard } 4883398db8f3b195959faa2a7cf09918f364432ac28Steve Howard 4896da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey public void dump(IndentingPrintWriter pw) { 4906da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.println("DownloadInfo:"); 4916da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.increaseIndent(); 4926da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey 4936da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.printPair("mId", mId); 4946da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.printPair("mLastMod", mLastMod); 4956da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.printPair("mPackage", mPackage); 4966da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.printPair("mUid", mUid); 4976da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.println(); 4986da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey 4996da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.printPair("mUri", mUri); 5006da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.println(); 5016da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey 5026da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.printPair("mMimeType", mMimeType); 5036da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.printPair("mCookies", (mCookies != null) ? "yes" : "no"); 5046da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.printPair("mReferer", (mReferer != null) ? "yes" : "no"); 5056da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.printPair("mUserAgent", mUserAgent); 5066da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.println(); 5076da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey 5086da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.printPair("mFileName", mFileName); 5096da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.printPair("mDestination", mDestination); 5106da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.println(); 5116da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey 5126da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.printPair("mStatus", Downloads.Impl.statusToString(mStatus)); 5136da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.printPair("mCurrentBytes", mCurrentBytes); 5146da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.printPair("mTotalBytes", mTotalBytes); 5156da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.println(); 5166da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey 5176da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.printPair("mNumFailed", mNumFailed); 5186da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.printPair("mRetryAfter", mRetryAfter); 5196da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.printPair("mETag", mETag); 5206da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.printPair("mIsPublicApi", mIsPublicApi); 5216da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.println(); 5226da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey 5236da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.printPair("mAllowedNetworkTypes", mAllowedNetworkTypes); 5246da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.printPair("mAllowRoaming", mAllowRoaming); 525a7ae77fdae69bcc6d6609d4639fed5d96e55eeaaJeff Sharkey pw.printPair("mAllowMetered", mAllowMetered); 5266da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.println(); 5276da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey 5286da2d0a2e1d046cd39270a46c3c77f8234f4cfaaJeff Sharkey pw.decreaseIndent(); 5293398db8f3b195959faa2a7cf09918f364432ac28Steve Howard } 5303398db8f3b195959faa2a7cf09918f364432ac28Steve Howard 5313398db8f3b195959faa2a7cf09918f364432ac28Steve Howard /** 5323398db8f3b195959faa2a7cf09918f364432ac28Steve Howard * Returns the amount of time (as measured from the "now" parameter) 5333398db8f3b195959faa2a7cf09918f364432ac28Steve Howard * at which a download will be active. 5343398db8f3b195959faa2a7cf09918f364432ac28Steve Howard * 0 = immediately - service should stick around to handle this download. 5353398db8f3b195959faa2a7cf09918f364432ac28Steve Howard * -1 = never - service can go away without ever waking up. 5363398db8f3b195959faa2a7cf09918f364432ac28Steve Howard * positive value - service must wake up in the future, as specified in ms from "now" 5373398db8f3b195959faa2a7cf09918f364432ac28Steve Howard */ 5383398db8f3b195959faa2a7cf09918f364432ac28Steve Howard long nextAction(long now) { 5393398db8f3b195959faa2a7cf09918f364432ac28Steve Howard if (Downloads.Impl.isStatusCompleted(mStatus)) { 5403398db8f3b195959faa2a7cf09918f364432ac28Steve Howard return -1; 5413398db8f3b195959faa2a7cf09918f364432ac28Steve Howard } 542b108a273b150e81bf26553b8851d6241bc711f98Steve Howard if (mStatus != Downloads.Impl.STATUS_WAITING_TO_RETRY) { 5433398db8f3b195959faa2a7cf09918f364432ac28Steve Howard return 0; 5443398db8f3b195959faa2a7cf09918f364432ac28Steve Howard } 545b108a273b150e81bf26553b8851d6241bc711f98Steve Howard long when = restartTime(now); 5463398db8f3b195959faa2a7cf09918f364432ac28Steve Howard if (when <= now) { 5473398db8f3b195959faa2a7cf09918f364432ac28Steve Howard return 0; 5483398db8f3b195959faa2a7cf09918f364432ac28Steve Howard } 5493398db8f3b195959faa2a7cf09918f364432ac28Steve Howard return when - now; 5503398db8f3b195959faa2a7cf09918f364432ac28Steve Howard } 5513398db8f3b195959faa2a7cf09918f364432ac28Steve Howard 5523398db8f3b195959faa2a7cf09918f364432ac28Steve Howard /** 5533398db8f3b195959faa2a7cf09918f364432ac28Steve Howard * Returns whether a file should be scanned 5543398db8f3b195959faa2a7cf09918f364432ac28Steve Howard */ 5553398db8f3b195959faa2a7cf09918f364432ac28Steve Howard boolean shouldScanFile() { 556b18ed519040c1ecd98f8cb139adcc315a3f4eedcVasu Nori return (mMediaScanned == 0) 557971525cbe68f83a4f05cfe942f774486702947a7Vasu Nori && (mDestination == Downloads.Impl.DESTINATION_EXTERNAL || 558b18ed519040c1ecd98f8cb139adcc315a3f4eedcVasu Nori mDestination == Downloads.Impl.DESTINATION_FILE_URI || 559b18ed519040c1ecd98f8cb139adcc315a3f4eedcVasu Nori mDestination == Downloads.Impl.DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD) 5600a17c2a28738d6ecb274def0e8e54f556d89f5f3Gloria Wang && Downloads.Impl.isStatusSuccess(mStatus); 5613398db8f3b195959faa2a7cf09918f364432ac28Steve Howard } 562d319729622da1893e895f2e35f41d01ecdca3705Steve Howard 563d319729622da1893e895f2e35f41d01ecdca3705Steve Howard void notifyPauseDueToSize(boolean isWifiRequired) { 564d319729622da1893e895f2e35f41d01ecdca3705Steve Howard Intent intent = new Intent(Intent.ACTION_VIEW); 565d319729622da1893e895f2e35f41d01ecdca3705Steve Howard intent.setData(getAllDownloadsUri()); 566d319729622da1893e895f2e35f41d01ecdca3705Steve Howard intent.setClassName(SizeLimitActivity.class.getPackage().getName(), 567d319729622da1893e895f2e35f41d01ecdca3705Steve Howard SizeLimitActivity.class.getName()); 568d319729622da1893e895f2e35f41d01ecdca3705Steve Howard intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 569d319729622da1893e895f2e35f41d01ecdca3705Steve Howard intent.putExtra(EXTRA_IS_WIFI_REQUIRED, isWifiRequired); 570d319729622da1893e895f2e35f41d01ecdca3705Steve Howard mContext.startActivity(intent); 571d319729622da1893e895f2e35f41d01ecdca3705Steve Howard } 5726baceb7073ed7858d3424ccf774e5f6a946bec59Vasu Nori 5736baceb7073ed7858d3424ccf774e5f6a946bec59Vasu Nori void startDownloadThread() { 5746baceb7073ed7858d3424ccf774e5f6a946bec59Vasu Nori DownloadThread downloader = new DownloadThread(mContext, mSystemFacade, this, 5756baceb7073ed7858d3424ccf774e5f6a946bec59Vasu Nori StorageManager.getInstance(mContext)); 5766baceb7073ed7858d3424ccf774e5f6a946bec59Vasu Nori mSystemFacade.startThread(downloader); 5776baceb7073ed7858d3424ccf774e5f6a946bec59Vasu Nori } 5782fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey 5792fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey /** 5802fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey * Query and return status of requested download. 5812fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey */ 5822fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey public static int queryDownloadStatus(ContentResolver resolver, long id) { 5832fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey final Cursor cursor = resolver.query( 5842fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey ContentUris.withAppendedId(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, id), 5852fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey new String[] { Downloads.Impl.COLUMN_STATUS }, null, null, null); 5862fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey try { 5872fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey if (cursor.moveToFirst()) { 5882fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey return cursor.getInt(0); 5892fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey } else { 5902fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey // TODO: increase strictness of value returned for unknown 5912fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey // downloads; this is safe default for now. 5922fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey return Downloads.Impl.STATUS_PENDING; 5932fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey } 5942fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey } finally { 5952fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey cursor.close(); 5962fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey } 5972fa007ef678b2283d47d007aa3dc91af683cc52cJeff Sharkey } 59857f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project} 599