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