BluetoothOppNotification.java revision 09e9cba205af60b3f42e7a4d891a7d1392e1f2a5
109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly/*
209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Copyright (c) 2008-2009, Motorola, Inc.
309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly *
409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * All rights reserved.
509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly *
609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Redistribution and use in source and binary forms, with or without
709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * modification, are permitted provided that the following conditions are met:
809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly *
909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * - Redistributions of source code must retain the above copyright notice,
1009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * this list of conditions and the following disclaimer.
1109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly *
1209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * - Redistributions in binary form must reproduce the above copyright notice,
1309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * this list of conditions and the following disclaimer in the documentation
1409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * and/or other materials provided with the distribution.
1509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly *
1609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * - Neither the name of the Motorola, Inc. nor the names of its contributors
1709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * may be used to endorse or promote products derived from this software
1809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * without specific prior written permission.
1909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly *
2009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
2409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * POSSIBILITY OF SUCH DAMAGE.
3109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */
3209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
3309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellypackage com.android.bluetooth.opp;
3409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
3509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.content.Context;
3609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.app.Notification;
3709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.app.NotificationManager;
3809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.app.PendingIntent;
3909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.content.Intent;
4009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.database.Cursor;
4109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.net.Uri;
4209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.util.Log;
4309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.widget.RemoteViews;
4409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.widget.Toast;
4509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport java.util.HashMap;
4609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
4709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly/**
4809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * This class handles the updating of the Notification Manager for the cases
4909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * where there is an ongoing transfer, incoming transfer need confirm and
5009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * complete (successful or failed) transfer.
5109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */
5209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyclass BluetoothOppNotification {
5309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private static final String TAG = "BluetoothOppNotification";
5409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
5509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    Context mContext;
5609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
5709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    public NotificationManager mNotificationMgr;
5809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
5909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    HashMap<String, NotificationItem> mNotifications;
6009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
6109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    static final String status = "(" + BluetoothShare.STATUS + " == '192'" + ")";
6209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
6309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    static final String visible = "(" + BluetoothShare.VISIBILITY + " IS NULL OR "
6409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            + BluetoothShare.VISIBILITY + " == '" + BluetoothShare.VISIBILITY_VISIBLE + "'" + ")";
6509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
6609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    static final String confirm = "(" + BluetoothShare.USER_CONFIRMATION + " == '"
6709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            + BluetoothShare.USER_CONFIRMATION_CONFIRMED + "' OR "
6809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            + BluetoothShare.USER_CONFIRMATION + " == '"
6909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            + BluetoothShare.USER_CONFIRMATION_AUTO_CONFIRMED + "'" + ")";
7009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
7109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    static final String WHERE_RUNNING = status + " AND " + visible + " AND " + confirm;
7209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
7309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    static final String WHERE_COMPLETED = BluetoothShare.STATUS + " >= '200' AND " + visible;
7409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
7509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    static final String WHERE_CONFIRM_PENDING = BluetoothShare.USER_CONFIRMATION + " == '"
7609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            + BluetoothShare.USER_CONFIRMATION_PENDING + "'" + " AND " + visible;
7709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
7809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    /**
7909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     * This inner class is used to describe some properties for one transfer.
8009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     */
8109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    static class NotificationItem {
8209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        int id; // This first field _id in db;
8309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
8409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        int direction; // to indicate sending or receiving
8509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
8609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        int totalCurrent = 0; // current transfer bytes
8709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
8809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        int totalTotal = 0; // total bytes for current transfer
8909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
9009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        String description; // the text above progress bar
9109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
9209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
9309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    /**
9409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     * Constructor
9509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     *
9609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     * @param ctx The context to use to obtain access to the Notification
9709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     *            Service
9809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     */
9909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    BluetoothOppNotification(Context ctx) {
10009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        mContext = ctx;
10109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        mNotificationMgr = (NotificationManager)mContext
10209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                .getSystemService(Context.NOTIFICATION_SERVICE);
10309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        mNotifications = new HashMap<String, NotificationItem>();
10409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
10509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
10609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    /**
10709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     * Update the notification ui.
10809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     */
10909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    public void updateNotification() {
11009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        updateActiveNotification();
11109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        updateCompletedNotification();
11209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        updateIncomingFileConfirmNotification();
11309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
11409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
11509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private void updateActiveNotification() {
11609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        // Active transfers
11709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        Cursor cursor = mContext.getContentResolver().query(BluetoothShare.CONTENT_URI, null,
11809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                WHERE_RUNNING, null, BluetoothShare._ID);
11909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (cursor == null) {
12009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            return;
12109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
12209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
12309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        // Collate the notifications
12409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        mNotifications.clear();
12509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
12609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            int timeStamp = cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.TIMESTAMP));
12709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            int dir = cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.DIRECTION));
12809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            int id = cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare._ID));
12909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            int total = cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.TOTAL_BYTES));
13009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            int current = cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.CURRENT_BYTES));
13109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
13209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            String fileName = cursor.getString(cursor.getColumnIndexOrThrow(BluetoothShare._DATA));
13309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            if (fileName == null) {
13409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                fileName = cursor.getString(cursor
13509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                        .getColumnIndexOrThrow(BluetoothShare.FILENAME_HINT));
13609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
13709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            if (fileName == null) {
13809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                fileName = mContext.getString(R.string.unknown_file);
13909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
14009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
14109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            String batchID = Long.toString(timeStamp);
14209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
14309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            // sending objects in one batch has same timeStamp
14409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            if (mNotifications.containsKey(batchID)) {
14509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                // NOTE: currently no such case
14609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                // Batch sending case
14709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            } else {
14809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                NotificationItem item = new NotificationItem();
14909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                item.id = id;
15009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                item.direction = dir;
15109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                if (item.direction == BluetoothShare.DIRECTION_OUTBOUND) {
15209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    item.description = mContext.getString(R.string.notification_sending).replace(
15309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                            "%s", fileName);
15409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                } else if (item.direction == BluetoothShare.DIRECTION_INBOUND) {
15509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    item.description = mContext.getString(R.string.notification_receiving).replace(
15609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                            "%s", fileName);
15709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                } else {
15809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    if (Constants.LOGVV) {
15909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                        Log.v(TAG, "mDirection ERROR!");
16009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    }
16109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                }
16209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                item.totalCurrent = current;
16309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                item.totalTotal = total;
16409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
16509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                mNotifications.put(batchID, item);
16609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
16709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                if (Constants.LOGVV) {
16809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    Log.v(TAG, "ID=" + item.id + "; batchID=" + batchID + "; totoalCurrent"
16909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                            + item.totalCurrent + "; totalTotal=" + item.totalTotal);
17009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                }
17109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
17209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
17309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        cursor.close();
17409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
17509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        // Add the notifications
17609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        for (NotificationItem item : mNotifications.values()) {
17709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            // Build the RemoteView object
17809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            RemoteViews expandedView = new RemoteViews(Constants.THIS_PACKAGE_NAME,
17909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    R.layout.status_bar_ongoing_event_progress_bar);
18009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
18109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            expandedView.setTextViewText(R.id.description, item.description);
18209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
18309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            expandedView.setProgressBar(R.id.progress_bar, item.totalTotal, item.totalCurrent,
18409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    item.totalTotal == -1);
18509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
18609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            expandedView.setTextViewText(R.id.progress_text, BluetoothOppUtility
18709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    .formatProgressText(item.totalTotal, item.totalCurrent));
18809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
18909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            // Build the notification object
19009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Notification n = new Notification();
19109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            if (item.direction == BluetoothShare.DIRECTION_OUTBOUND) {
19209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                n.icon = android.R.drawable.stat_sys_upload;
19309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                expandedView.setImageViewResource(R.id.appIcon, android.R.drawable.stat_sys_upload);
19409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            } else if (item.direction == BluetoothShare.DIRECTION_INBOUND) {
19509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                n.icon = android.R.drawable.stat_sys_download;
19609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                expandedView.setImageViewResource(R.id.appIcon,
19709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                        android.R.drawable.stat_sys_download);
19809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            } else {
19909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                if (Constants.LOGVV) {
20009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    Log.v(TAG, "mDirection ERROR!");
20109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                }
20209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
20309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
20409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            n.flags |= Notification.FLAG_ONGOING_EVENT;
20509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            n.contentView = expandedView;
20609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
20709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Intent intent = new Intent(Constants.ACTION_LIST);
20809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            intent.setClassName(Constants.THIS_PACKAGE_NAME, BluetoothOppReceiver.class.getName());
20909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            intent.setData(Uri.parse(BluetoothShare.CONTENT_URI + "/" + item.id));
21009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
21109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            n.contentIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
21209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            mNotificationMgr.notify(item.id, n);
21309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
21409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
21509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
21609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private void updateCompletedNotification() {
21709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        Cursor cursor = mContext.getContentResolver().query(BluetoothShare.CONTENT_URI, null,
21809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                WHERE_COMPLETED, null, BluetoothShare._ID);
21909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (cursor == null) {
22009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            return;
22109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
22209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
22309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
22409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            // Add the notifications
22509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            int timeStamp = cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.TIMESTAMP));
22609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            int dir = cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.DIRECTION));
22709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            int id = cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare._ID));
22809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            int status = cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.STATUS));
22909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
23009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            String fileName = cursor.getString(cursor.getColumnIndexOrThrow(BluetoothShare._DATA));
23109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            if (fileName == null) {
23209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                fileName = cursor.getString(cursor
23309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                        .getColumnIndexOrThrow(BluetoothShare.FILENAME_HINT));
23409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
23509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            if (fileName == null) {
23609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                fileName = mContext.getString(R.string.unknown_file);
23709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
23809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
23909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            String title;
24009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            String caption;
24109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + id);
24209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
24309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Notification n = new Notification();
24409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            if (BluetoothShare.isStatusError(status)) {
24509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                if (dir == BluetoothShare.DIRECTION_OUTBOUND) {
24609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    title = mContext.getString(R.string.notification_sent_fail).replace("%s",
24709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                            fileName);
24809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                } else {
24909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    title = mContext.getString(R.string.notification_received_fail).replace("%s",
25009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                            fileName);
25109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                }
25209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                caption = mContext.getString(R.string.download_fail_line3).replace("%s",
25309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                        BluetoothOppUtility.getStatusDescription(mContext, status));
25409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                n.icon = android.R.drawable.stat_notify_error;
25509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            } else {
25609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                if (dir == BluetoothShare.DIRECTION_OUTBOUND) {
25709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    title = mContext.getString(R.string.notification_sent).replace("%s", fileName);
25809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    n.icon = android.R.drawable.stat_sys_upload_done;
25909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                } else {
26009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    title = mContext.getString(R.string.notification_received).replace("%s",
26109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                            fileName);
26209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    n.icon = android.R.drawable.stat_sys_download_done;
26309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                }
26409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                caption = mContext.getString(R.string.notification_sent_complete);
26509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
26609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Intent intent = new Intent(Constants.ACTION_OPEN);
26709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            intent.setClassName(Constants.THIS_PACKAGE_NAME, BluetoothOppReceiver.class.getName());
26809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            intent.setData(contentUri);
26909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
27009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            n.setLatestEventInfo(mContext, title, caption, PendingIntent.getBroadcast(mContext, 0,
27109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    intent, 0));
27209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
27309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            intent = new Intent(Constants.ACTION_HIDE);
27409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            intent.setClassName(Constants.THIS_PACKAGE_NAME, BluetoothOppReceiver.class.getName());
27509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            intent.setData(contentUri);
27609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            n.deleteIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
27709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
27809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            n.when = timeStamp;
27909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
28009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            mNotificationMgr.notify(id, n);
28109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
28209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        cursor.close();
28309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
28409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
28509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private void updateIncomingFileConfirmNotification() {
28609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        Cursor cursor = mContext.getContentResolver().query(BluetoothShare.CONTENT_URI, null,
28709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                WHERE_CONFIRM_PENDING, null, BluetoothShare._ID);
28809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
28909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (cursor == null) {
29009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            return;
29109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
29209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
29309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
29409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            String title = mContext.getString(R.string.incoming_file_confirm_Notification_title);
29509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            String caption = mContext
29609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    .getString(R.string.incoming_file_confirm_Notification_caption);
29709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            int id = cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare._ID));
29809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            int timeStamp = cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.TIMESTAMP));
29909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + id);
30009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
30109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Notification n = new Notification();
30209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            n.icon = R.drawable.stat_sys_data_bt;
30309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            n.flags |= Notification.FLAG_ONLY_ALERT_ONCE;
30409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            n.defaults = Notification.DEFAULT_SOUND;
30509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            n.tickerText = title;
30609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Intent intent = new Intent(Constants.ACTION_INCOMING_FILE_CONFIRM);
30709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            intent.setClassName(Constants.THIS_PACKAGE_NAME, BluetoothOppReceiver.class.getName());
30809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            intent.setData(contentUri);
30909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            n.setLatestEventInfo(mContext, title, caption, PendingIntent.getBroadcast(mContext, 0,
31009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                    intent, 0));
31109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
31209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            intent = new Intent(Constants.ACTION_HIDE);
31309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            intent.setClassName(Constants.THIS_PACKAGE_NAME, BluetoothOppReceiver.class.getName());
31409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            intent.setData(contentUri);
31509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            n.deleteIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
31609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
31709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            n.when = timeStamp;
31809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            mNotificationMgr.notify(id, n);
31909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
32009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        cursor.close();
32109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
32209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly}
323