1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.providers.downloads; 18 19import android.content.res.Resources; 20import android.util.Log; 21import android.util.LongSparseArray; 22 23import com.android.internal.annotations.GuardedBy; 24 25import java.util.ArrayList; 26import java.util.HashMap; 27import java.util.Iterator; 28import java.util.LinkedHashMap; 29 30public class DownloadHandler { 31 private static final String TAG = "DownloadHandler"; 32 33 @GuardedBy("this") 34 private final LinkedHashMap<Long, DownloadInfo> mDownloadsQueue = 35 new LinkedHashMap<Long, DownloadInfo>(); 36 @GuardedBy("this") 37 private final HashMap<Long, DownloadInfo> mDownloadsInProgress = 38 new HashMap<Long, DownloadInfo>(); 39 @GuardedBy("this") 40 private final LongSparseArray<Long> mCurrentSpeed = new LongSparseArray<Long>(); 41 42 private final int mMaxConcurrentDownloadsAllowed = Resources.getSystem().getInteger( 43 com.android.internal.R.integer.config_MaxConcurrentDownloadsAllowed); 44 45 private static final DownloadHandler sDownloadHandler = new DownloadHandler(); 46 47 public static DownloadHandler getInstance() { 48 return sDownloadHandler; 49 } 50 51 public synchronized void enqueueDownload(DownloadInfo info) { 52 if (!mDownloadsQueue.containsKey(info.mId)) { 53 if (Constants.LOGV) { 54 Log.i(TAG, "enqueued download. id: " + info.mId + ", uri: " + info.mUri); 55 } 56 mDownloadsQueue.put(info.mId, info); 57 startDownloadThreadLocked(); 58 } 59 } 60 61 private void startDownloadThreadLocked() { 62 Iterator<Long> keys = mDownloadsQueue.keySet().iterator(); 63 ArrayList<Long> ids = new ArrayList<Long>(); 64 while (mDownloadsInProgress.size() < mMaxConcurrentDownloadsAllowed && keys.hasNext()) { 65 Long id = keys.next(); 66 DownloadInfo info = mDownloadsQueue.get(id); 67 info.startDownloadThread(); 68 ids.add(id); 69 mDownloadsInProgress.put(id, mDownloadsQueue.get(id)); 70 if (Constants.LOGV) { 71 Log.i(TAG, "started download for : " + id); 72 } 73 } 74 for (Long id : ids) { 75 mDownloadsQueue.remove(id); 76 } 77 } 78 79 public synchronized boolean hasDownloadInQueue(long id) { 80 return mDownloadsQueue.containsKey(id) || mDownloadsInProgress.containsKey(id); 81 } 82 83 public synchronized void dequeueDownload(long id) { 84 mDownloadsInProgress.remove(id); 85 mCurrentSpeed.remove(id); 86 startDownloadThreadLocked(); 87 if (mDownloadsInProgress.size() == 0 && mDownloadsQueue.size() == 0) { 88 notifyAll(); 89 } 90 } 91 92 public synchronized void setCurrentSpeed(long id, long speed) { 93 mCurrentSpeed.put(id, speed); 94 } 95 96 public synchronized long getCurrentSpeed(long id) { 97 return mCurrentSpeed.get(id, -1L); 98 } 99 100 // right now this is only used by tests. but there is no reason why it can't be used 101 // by any module using DownloadManager (TODO add API to DownloadManager.java) 102 public synchronized void waitUntilDownloadsTerminate() throws InterruptedException { 103 if (mDownloadsInProgress.size() == 0 && mDownloadsQueue.size() == 0) { 104 if (Constants.LOGVV) { 105 Log.i(TAG, "nothing to wait on"); 106 } 107 return; 108 } 109 if (Constants.LOGVV) { 110 for (DownloadInfo info : mDownloadsInProgress.values()) { 111 Log.i(TAG, "** progress: " + info.mId + ", " + info.mUri); 112 } 113 for (DownloadInfo info : mDownloadsQueue.values()) { 114 Log.i(TAG, "** in Q: " + info.mId + ", " + info.mUri); 115 } 116 } 117 if (Constants.LOGVV) { 118 Log.i(TAG, "waiting for 5 sec"); 119 } 120 // wait upto 5 sec 121 wait(5 * 1000); 122 } 123} 124