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 1957f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Projectimport android.app.Notification; 2057f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Projectimport android.app.PendingIntent; 213d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howardimport android.content.ContentUris; 2257f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Projectimport android.content.Context; 2357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Projectimport android.content.Intent; 2457f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Projectimport android.net.Uri; 2557f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Projectimport android.provider.Downloads; 26c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkeyimport android.text.TextUtils; 2757f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project 283398db8f3b195959faa2a7cf09918f364432ac28Steve Howardimport java.util.Collection; 2957f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Projectimport java.util.HashMap; 3057f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project 3157f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project/** 32ec9106456e6d98b70a90ac4d7618cdfd05a5ba2bSteve Howard * This class handles the updating of the Notification Manager for the 3357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project * cases where there is an ongoing download. Once the download is complete 34ec9106456e6d98b70a90ac4d7618cdfd05a5ba2bSteve Howard * (be it successful or unsuccessful) it is no longer the responsibility 3557f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project * of this component to show the download in the notification manager. 3657f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project * 3757f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project */ 3857f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Projectclass DownloadNotification { 3957f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project 4057f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project Context mContext; 4157f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project HashMap <String, NotificationItem> mNotifications; 4293155e1da7e89d4925e244f5afa94afb8ada7381Steve Howard private SystemFacade mSystemFacade; 43ec9106456e6d98b70a90ac4d7618cdfd05a5ba2bSteve Howard 4457f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project static final String LOGTAG = "DownloadNotification"; 45ec9106456e6d98b70a90ac4d7618cdfd05a5ba2bSteve Howard static final String WHERE_RUNNING = 467dd92fa94df0a13b4592ee636b7aa2b605f6b473Jean-Baptiste Queru "(" + Downloads.Impl.COLUMN_STATUS + " >= '100') AND (" + 477dd92fa94df0a13b4592ee636b7aa2b605f6b473Jean-Baptiste Queru Downloads.Impl.COLUMN_STATUS + " <= '199') AND (" + 487dd92fa94df0a13b4592ee636b7aa2b605f6b473Jean-Baptiste Queru Downloads.Impl.COLUMN_VISIBILITY + " IS NULL OR " + 497dd92fa94df0a13b4592ee636b7aa2b605f6b473Jean-Baptiste Queru Downloads.Impl.COLUMN_VISIBILITY + " == '" + Downloads.Impl.VISIBILITY_VISIBLE + "' OR " + 507dd92fa94df0a13b4592ee636b7aa2b605f6b473Jean-Baptiste Queru Downloads.Impl.COLUMN_VISIBILITY + 517dd92fa94df0a13b4592ee636b7aa2b605f6b473Jean-Baptiste Queru " == '" + Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED + "')"; 521fbad9cfa532f13f6cf03f542febf2e4689edec5The Android Open Source Project static final String WHERE_COMPLETED = 537dd92fa94df0a13b4592ee636b7aa2b605f6b473Jean-Baptiste Queru Downloads.Impl.COLUMN_STATUS + " >= '200' AND " + 547dd92fa94df0a13b4592ee636b7aa2b605f6b473Jean-Baptiste Queru Downloads.Impl.COLUMN_VISIBILITY + 557dd92fa94df0a13b4592ee636b7aa2b605f6b473Jean-Baptiste Queru " == '" + Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED + "'"; 56ec9106456e6d98b70a90ac4d7618cdfd05a5ba2bSteve Howard 57ec9106456e6d98b70a90ac4d7618cdfd05a5ba2bSteve Howard 5857f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project /** 5957f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project * This inner class is used to collate downloads that are owned by 6057f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project * the same application. This is so that only one notification line 6157f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project * item is used for all downloads of a given application. 6257f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project * 6357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project */ 6457f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project static class NotificationItem { 65c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru int mId; // This first db _id for the download for the app 6697d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard long mTotalCurrent = 0; 6797d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard long mTotalTotal = 0; 68c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru int mTitleCount = 0; 69c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru String mPackageName; // App package name 70c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru String mDescription; 71c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru String[] mTitles = new String[2]; // download titles. 7297d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard String mPausedText = null; 73ec9106456e6d98b70a90ac4d7618cdfd05a5ba2bSteve Howard 7457f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project /* 7557f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project * Add a second download to this notification item. 7657f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project */ 7797d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard void addItem(String title, long currentBytes, long totalBytes) { 78c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru mTotalCurrent += currentBytes; 79c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru if (totalBytes <= 0 || mTotalTotal == -1) { 80c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru mTotalTotal = -1; 8157f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } else { 82c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru mTotalTotal += totalBytes; 8357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } 84c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru if (mTitleCount < 2) { 85c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru mTitles[mTitleCount] = title; 8657f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } 87c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru mTitleCount++; 8857f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } 8957f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } 90ec9106456e6d98b70a90ac4d7618cdfd05a5ba2bSteve Howard 91ec9106456e6d98b70a90ac4d7618cdfd05a5ba2bSteve Howard 9257f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project /** 9357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project * Constructor 94ec9106456e6d98b70a90ac4d7618cdfd05a5ba2bSteve Howard * @param ctx The context to use to obtain access to the 9557f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project * Notification Service 9657f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project */ 9793155e1da7e89d4925e244f5afa94afb8ada7381Steve Howard DownloadNotification(Context ctx, SystemFacade systemFacade) { 9857f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project mContext = ctx; 9993155e1da7e89d4925e244f5afa94afb8ada7381Steve Howard mSystemFacade = systemFacade; 10057f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project mNotifications = new HashMap<String, NotificationItem>(); 10157f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } 102ec9106456e6d98b70a90ac4d7618cdfd05a5ba2bSteve Howard 10357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project /* 104ec9106456e6d98b70a90ac4d7618cdfd05a5ba2bSteve Howard * Update the notification ui. 10557f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project */ 1063398db8f3b195959faa2a7cf09918f364432ac28Steve Howard public void updateNotification(Collection<DownloadInfo> downloads) { 10797d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard updateActiveNotification(downloads); 10897d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard updateCompletedNotification(downloads); 10957f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } 11057f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project 1113398db8f3b195959faa2a7cf09918f364432ac28Steve Howard private void updateActiveNotification(Collection<DownloadInfo> downloads) { 11257f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project // Collate the notifications 11357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project mNotifications.clear(); 11497d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard for (DownloadInfo download : downloads) { 11597d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard if (!isActiveAndVisible(download)) { 11697d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard continue; 11797d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard } 11897d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard String packageName = download.mPackage; 11997d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard long max = download.mTotalBytes; 12097d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard long progress = download.mCurrentBytes; 12197d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard long id = download.mId; 12297d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard String title = download.mTitle; 12357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project if (title == null || title.length() == 0) { 124a2028ed4141075da8199ba04a499be77734a85aeLeon Scroggins title = mContext.getResources().getString( 125a2028ed4141075da8199ba04a499be77734a85aeLeon Scroggins R.string.download_unknown_title); 12657f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } 12797d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard 12897d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard NotificationItem item; 12957f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project if (mNotifications.containsKey(packageName)) { 13097d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard item = mNotifications.get(packageName); 13197d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard item.addItem(title, progress, max); 13257f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } else { 13397d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard item = new NotificationItem(); 1344d3a380d338b1f6ee120fb9de2001f138be398ffLeon Scroggins item.mId = (int) id; 135c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru item.mPackageName = packageName; 13697d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard item.mDescription = download.mDescription; 13757f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project item.addItem(title, progress, max); 13857f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project mNotifications.put(packageName, item); 13957f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } 140b108a273b150e81bf26553b8851d6241bc711f98Steve Howard if (download.mStatus == Downloads.Impl.STATUS_QUEUED_FOR_WIFI 141b108a273b150e81bf26553b8851d6241bc711f98Steve Howard && item.mPausedText == null) { 142b108a273b150e81bf26553b8851d6241bc711f98Steve Howard item.mPausedText = mContext.getResources().getString( 143b108a273b150e81bf26553b8851d6241bc711f98Steve Howard R.string.notification_need_wifi_for_size); 14497d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard } 14557f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } 146ec9106456e6d98b70a90ac4d7618cdfd05a5ba2bSteve Howard 14757f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project // Add the notifications 14857f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project for (NotificationItem item : mNotifications.values()) { 14957f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project // Build the notification object 150c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey final Notification.Builder builder = new Notification.Builder(mContext); 15197d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard 15297d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard boolean hasPausedText = (item.mPausedText != null); 153c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey int iconResource = android.R.drawable.stat_sys_download_done; 15497d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard if (hasPausedText) { 15597d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard iconResource = android.R.drawable.stat_sys_warning; 15697d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard } 157c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey builder.setSmallIcon(iconResource); 158c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey builder.setOngoing(true); 15957f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project 160c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey boolean hasContentText = false; 161c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru StringBuilder title = new StringBuilder(item.mTitles[0]); 162c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru if (item.mTitleCount > 1) { 16357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project title.append(mContext.getString(R.string.notification_filename_separator)); 164c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru title.append(item.mTitles[1]); 165c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru if (item.mTitleCount > 2) { 16657f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project title.append(mContext.getString(R.string.notification_filename_extras, 167c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru new Object[] { Integer.valueOf(item.mTitleCount - 2) })); 16857f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } 169c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey } else if (!TextUtils.isEmpty(item.mDescription)) { 170c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey builder.setContentText(item.mDescription); 171c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey hasContentText = true; 17257f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } 173c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey builder.setContentTitle(title); 17497d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard 17597d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard if (hasPausedText) { 176c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey builder.setContentText(item.mPausedText); 17797d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard } else { 178c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey builder.setProgress( 179c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey (int) item.mTotalTotal, (int) item.mTotalCurrent, item.mTotalTotal == -1); 180c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey if (hasContentText) { 181c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey builder.setContentInfo( 182c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey buildPercentageLabel(mContext, item.mTotalTotal, item.mTotalCurrent)); 183c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey } 18497d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard } 18557f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project 18657f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project Intent intent = new Intent(Constants.ACTION_LIST); 18757f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project intent.setClassName("com.android.providers.downloads", 18857f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project DownloadReceiver.class.getName()); 1893398db8f3b195959faa2a7cf09918f364432ac28Steve Howard intent.setData( 1903398db8f3b195959faa2a7cf09918f364432ac28Steve Howard ContentUris.withAppendedId(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, item.mId)); 191c6f5aad265cfc36a64cd2bdb5adf3cc9736bbd80Jean-Baptiste Queru intent.putExtra("multiple", item.mTitleCount > 1); 19257f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project 193c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey builder.setContentIntent(PendingIntent.getBroadcast(mContext, 0, intent, 0)); 19457f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project 195c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey mSystemFacade.postNotification(item.mId, builder.getNotification()); 196ec9106456e6d98b70a90ac4d7618cdfd05a5ba2bSteve Howard 19757f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } 19857f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } 19957f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project 2003398db8f3b195959faa2a7cf09918f364432ac28Steve Howard private void updateCompletedNotification(Collection<DownloadInfo> downloads) { 20197d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard for (DownloadInfo download : downloads) { 20297d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard if (!isCompleteAndVisible(download)) { 203cae0c3610fce7336c06377698e22878d110b19d2Steve Howard continue; 20497d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard } 2052c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori notificationForCompletedDownload(download.mId, download.mTitle, 2062c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori download.mStatus, download.mDestination, download.mLastMod); 2072c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori } 2082c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori } 2092c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori void notificationForCompletedDownload(long id, String title, int status, 2102c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori int destination, long lastMod) { 2112c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori // Add the notifications 212c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey Notification.Builder builder = new Notification.Builder(mContext); 213c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey builder.setSmallIcon(android.R.drawable.stat_sys_download_done); 2142c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori if (title == null || title.length() == 0) { 2152c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori title = mContext.getResources().getString( 2162c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori R.string.download_unknown_title); 2172c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori } 2182c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori Uri contentUri = 2192c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori ContentUris.withAppendedId(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, id); 2202c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori String caption; 2212c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori Intent intent; 2222c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori if (Downloads.Impl.isStatusError(status)) { 2232c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori caption = mContext.getResources() 2242c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori .getString(R.string.notification_download_failed); 2252c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori intent = new Intent(Constants.ACTION_LIST); 2262c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori } else { 2272c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori caption = mContext.getResources() 2282c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori .getString(R.string.notification_download_complete); 2292c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori if (destination != Downloads.Impl.DESTINATION_SYSTEMCACHE_PARTITION) { 2302c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori intent = new Intent(Constants.ACTION_OPEN); 23157f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } else { 2322c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori intent = new Intent(Constants.ACTION_LIST); 23357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } 2342c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori } 2352c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori intent.setClassName("com.android.providers.downloads", 2362c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori DownloadReceiver.class.getName()); 2372c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori intent.setData(contentUri); 23818c3040260907472a9e471e5707a5b2f8320d074Lixin Yue 239c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey builder.setWhen(lastMod); 240c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey builder.setContentTitle(title); 241c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey builder.setContentText(caption); 242c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey builder.setContentIntent(PendingIntent.getBroadcast(mContext, 0, intent, 0)); 24357f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project 2442c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori intent = new Intent(Constants.ACTION_HIDE); 2452c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori intent.setClassName("com.android.providers.downloads", 2462c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori DownloadReceiver.class.getName()); 2472c02577af19bf11714220d14cfc96d2c017ac1abVasu Nori intent.setData(contentUri); 248c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey builder.setDeleteIntent(PendingIntent.getBroadcast(mContext, 0, intent, 0)); 24957f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project 250c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey mSystemFacade.postNotification(id, builder.getNotification()); 25197d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard } 25297d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard 25397d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard private boolean isActiveAndVisible(DownloadInfo download) { 25497d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard return 100 <= download.mStatus && download.mStatus < 200 25504f09085f85d094207d22ae8969102bd48178180Vasu Nori && download.mVisibility != Downloads.Impl.VISIBILITY_HIDDEN; 25697d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard } 25797d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard 25897d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard private boolean isCompleteAndVisible(DownloadInfo download) { 25997d590d5a1f583acb7992d20851bdc6cd0454d12Steve Howard return download.mStatus >= 200 26004f09085f85d094207d22ae8969102bd48178180Vasu Nori && download.mVisibility == Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED; 26157f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } 26257f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project 263c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey private static String buildPercentageLabel( 264c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey Context context, long totalBytes, long currentBytes) { 26557f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project if (totalBytes <= 0) { 266c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey return null; 267c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey } else { 268c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey final int percent = (int) (100 * currentBytes / totalBytes); 269c18b41eef6da088ed968f2efeda55efcc62d80f5Jeff Sharkey return context.getString(R.string.download_percent, percent); 27057f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } 27157f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project } 27257f55b3cb4f7e4136cde8d1ea12c1e70ec90336The Android Open Source Project} 273