/*
 * Copyright (c) 2008-2009, Motorola, Inc.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * - Neither the name of the Motorola, Inc. nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package com.android.bluetooth.opp;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.os.Process;
import android.text.format.Formatter;
import android.util.Log;

import com.android.bluetooth.R;

import java.util.HashMap;

/**
 * This class handles the updating of the Notification Manager for the cases
 * where there is an ongoing transfer, incoming transfer need confirm and
 * complete (successful or failed) transfer.
 */
class BluetoothOppNotification {
    private static final String TAG = "BluetoothOppNotification";
    private static final boolean V = Constants.VERBOSE;

    static final String STATUS = "(" + BluetoothShare.STATUS + " == '192'" + ")";

    static final String VISIBLE =
            "(" + BluetoothShare.VISIBILITY + " IS NULL OR " + BluetoothShare.VISIBILITY + " == '"
                    + BluetoothShare.VISIBILITY_VISIBLE + "'" + ")";

    static final String CONFIRM = "(" + BluetoothShare.USER_CONFIRMATION + " == '"
            + BluetoothShare.USER_CONFIRMATION_CONFIRMED + "' OR "
            + BluetoothShare.USER_CONFIRMATION + " == '"
            + BluetoothShare.USER_CONFIRMATION_AUTO_CONFIRMED + "' OR "
            + BluetoothShare.USER_CONFIRMATION + " == '"
            + BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED + "'" + ")";

    static final String NOT_THROUGH_HANDOVER = "(" + BluetoothShare.USER_CONFIRMATION + " != '"
            + BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED + "'" + ")";

    static final String WHERE_RUNNING = STATUS + " AND " + VISIBLE + " AND " + CONFIRM;

    static final String WHERE_COMPLETED =
            BluetoothShare.STATUS + " >= '200' AND " + VISIBLE + " AND " + NOT_THROUGH_HANDOVER;
    // Don't show handover-initiated transfers

    private static final String WHERE_COMPLETED_OUTBOUND =
            WHERE_COMPLETED + " AND " + "(" + BluetoothShare.DIRECTION + " == "
                    + BluetoothShare.DIRECTION_OUTBOUND + ")";

    private static final String WHERE_COMPLETED_INBOUND =
            WHERE_COMPLETED + " AND " + "(" + BluetoothShare.DIRECTION + " == "
                    + BluetoothShare.DIRECTION_INBOUND + ")";

    static final String WHERE_CONFIRM_PENDING =
            BluetoothShare.USER_CONFIRMATION + " == '" + BluetoothShare.USER_CONFIRMATION_PENDING
                    + "'" + " AND " + VISIBLE;

    public NotificationManager mNotificationMgr;

    private NotificationChannel mNotificationChannel;
    private static final String OPP_NOTIFICATION_CHANNEL = "opp_notification_channel";

    private Context mContext;

    private HashMap<String, NotificationItem> mNotifications;

    private NotificationUpdateThread mUpdateNotificationThread;

    private int mPendingUpdate = 0;

    public static final int NOTIFICATION_ID_PROGRESS = -1000004;

    private static final int NOTIFICATION_ID_OUTBOUND_COMPLETE = -1000005;

    private static final int NOTIFICATION_ID_INBOUND_COMPLETE = -1000006;

    private boolean mUpdateCompleteNotification = true;

    private ContentResolver mContentResolver = null;

    /**
     * This inner class is used to describe some properties for one transfer.
     */
    static class NotificationItem {
        public int id; // This first field _id in db;

        public int direction; // to indicate sending or receiving

        public long totalCurrent = 0; // current transfer bytes

        public long totalTotal = 0; // total bytes for current transfer

        public long timeStamp = 0; // Database time stamp. Used for sorting ongoing transfers.

        public String description; // the text above progress bar

        public boolean handoverInitiated = false;
        // transfer initiated by connection handover (eg NFC)

        public String destination; // destination associated with this transfer
    }

    /**
     * Constructor
     *
     * @param ctx The context to use to obtain access to the Notification
     *            Service
     */
    BluetoothOppNotification(Context ctx) {
        mContext = ctx;
        mNotificationMgr =
                (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationChannel = new NotificationChannel(OPP_NOTIFICATION_CHANNEL,
                mContext.getString(R.string.opp_notification_group),
                NotificationManager.IMPORTANCE_HIGH);

        mNotificationMgr.createNotificationChannel(mNotificationChannel);
        mNotifications = new HashMap<String, NotificationItem>();
        // Get Content Resolver object one time
        mContentResolver = mContext.getContentResolver();
    }

    /**
     * Update the notification ui.
     */
    public void updateNotification() {
        synchronized (BluetoothOppNotification.this) {
            mPendingUpdate++;
            if (mPendingUpdate > 1) {
                if (V) {
                    Log.v(TAG, "update too frequent, put in queue");
                }
                return;
            }
            if (!mHandler.hasMessages(NOTIFY)) {
                if (V) {
                    Log.v(TAG, "send message");
                }
                mHandler.sendMessage(mHandler.obtainMessage(NOTIFY));
            }
        }
    }

    private static final int NOTIFY = 0;
    // Use 1 second timer to limit notification frequency.
    // 1. On the first notification, create the update thread.
    //    Buffer other updates.
    // 2. Update thread will clear mPendingUpdate.
    // 3. Handler sends a delayed message to self
    // 4. Handler checks if there are any more updates after 1 second.
    // 5. If there is an update, update it else stop.
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case NOTIFY:
                    synchronized (BluetoothOppNotification.this) {
                        if (mPendingUpdate > 0 && mUpdateNotificationThread == null) {
                            if (V) {
                                Log.v(TAG, "new notify threadi!");
                            }
                            mUpdateNotificationThread = new NotificationUpdateThread();
                            mUpdateNotificationThread.start();
                            if (V) {
                                Log.v(TAG, "send delay message");
                            }
                            mHandler.sendMessageDelayed(mHandler.obtainMessage(NOTIFY), 1000);
                        } else if (mPendingUpdate > 0) {
                            if (V) {
                                Log.v(TAG, "previous thread is not finished yet");
                            }
                            mHandler.sendMessageDelayed(mHandler.obtainMessage(NOTIFY), 1000);
                        }
                        break;
                    }
            }
        }
    };

    private class NotificationUpdateThread extends Thread {

        NotificationUpdateThread() {
            super("Notification Update Thread");
        }

        @Override
        public void run() {
            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
            synchronized (BluetoothOppNotification.this) {
                if (mUpdateNotificationThread != this) {
                    throw new IllegalStateException(
                            "multiple UpdateThreads in BluetoothOppNotification");
                }
                mPendingUpdate = 0;
            }
            updateActiveNotification();
            updateCompletedNotification();
            updateIncomingFileConfirmNotification();
            synchronized (BluetoothOppNotification.this) {
                mUpdateNotificationThread = null;
            }
        }
    }

    private void updateActiveNotification() {
        // Active transfers
        Cursor cursor =
                mContentResolver.query(BluetoothShare.CONTENT_URI, null, WHERE_RUNNING, null,
                        BluetoothShare._ID);
        if (cursor == null) {
            return;
        }

        // If there is active transfers, then no need to update completed transfer
        // notifications
        if (cursor.getCount() > 0) {
            mUpdateCompleteNotification = false;
        } else {
            mUpdateCompleteNotification = true;
        }
        if (V) {
            Log.v(TAG, "mUpdateCompleteNotification = " + mUpdateCompleteNotification);
        }

        // Collate the notifications
        final int timestampIndex = cursor.getColumnIndexOrThrow(BluetoothShare.TIMESTAMP);
        final int directionIndex = cursor.getColumnIndexOrThrow(BluetoothShare.DIRECTION);
        final int idIndex = cursor.getColumnIndexOrThrow(BluetoothShare._ID);
        final int totalBytesIndex = cursor.getColumnIndexOrThrow(BluetoothShare.TOTAL_BYTES);
        final int currentBytesIndex = cursor.getColumnIndexOrThrow(BluetoothShare.CURRENT_BYTES);
        final int dataIndex = cursor.getColumnIndexOrThrow(BluetoothShare._DATA);
        final int filenameHintIndex = cursor.getColumnIndexOrThrow(BluetoothShare.FILENAME_HINT);
        final int confirmIndex = cursor.getColumnIndexOrThrow(BluetoothShare.USER_CONFIRMATION);
        final int destinationIndex = cursor.getColumnIndexOrThrow(BluetoothShare.DESTINATION);

        mNotifications.clear();
        for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
            long timeStamp = cursor.getLong(timestampIndex);
            int dir = cursor.getInt(directionIndex);
            int id = cursor.getInt(idIndex);
            long total = cursor.getLong(totalBytesIndex);
            long current = cursor.getLong(currentBytesIndex);
            int confirmation = cursor.getInt(confirmIndex);

            String destination = cursor.getString(destinationIndex);
            String fileName = cursor.getString(dataIndex);
            if (fileName == null) {
                fileName = cursor.getString(filenameHintIndex);
            }
            if (fileName == null) {
                fileName = mContext.getString(R.string.unknown_file);
            }

            String batchID = Long.toString(timeStamp);

            // sending objects in one batch has same timeStamp
            if (mNotifications.containsKey(batchID)) {
                // NOTE: currently no such case
                // Batch sending case
            } else {
                NotificationItem item = new NotificationItem();
                item.timeStamp = timeStamp;
                item.id = id;
                item.direction = dir;
                if (item.direction == BluetoothShare.DIRECTION_OUTBOUND) {
                    item.description = mContext.getString(R.string.notification_sending, fileName);
                } else if (item.direction == BluetoothShare.DIRECTION_INBOUND) {
                    item.description =
                            mContext.getString(R.string.notification_receiving, fileName);
                } else {
                    if (V) {
                        Log.v(TAG, "mDirection ERROR!");
                    }
                }
                item.totalCurrent = current;
                item.totalTotal = total;
                item.handoverInitiated =
                        confirmation == BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED;
                item.destination = destination;
                mNotifications.put(batchID, item);

                if (V) {
                    Log.v(TAG, "ID=" + item.id + "; batchID=" + batchID + "; totoalCurrent"
                            + item.totalCurrent + "; totalTotal=" + item.totalTotal);
                }
            }
        }
        cursor.close();

        // Add the notifications
        for (NotificationItem item : mNotifications.values()) {
            if (item.handoverInitiated) {
                float progress = 0;
                if (item.totalTotal == -1) {
                    progress = -1;
                } else {
                    progress = (float) item.totalCurrent / item.totalTotal;
                }

                // Let NFC service deal with notifications for this transfer
                Intent intent = new Intent(Constants.ACTION_BT_OPP_TRANSFER_PROGRESS);
                if (item.direction == BluetoothShare.DIRECTION_INBOUND) {
                    intent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_DIRECTION,
                            Constants.DIRECTION_BLUETOOTH_INCOMING);
                } else {
                    intent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_DIRECTION,
                            Constants.DIRECTION_BLUETOOTH_OUTGOING);
                }
                intent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_ID, item.id);
                intent.putExtra(Constants.EXTRA_BT_OPP_TRANSFER_PROGRESS, progress);
                intent.putExtra(Constants.EXTRA_BT_OPP_ADDRESS, item.destination);
                mContext.sendBroadcast(intent, Constants.HANDOVER_STATUS_PERMISSION);
                continue;
            }
            // Build the notification object
            // TODO: split description into two rows with filename in second row
            Notification.Builder b = new Notification.Builder(mContext, OPP_NOTIFICATION_CHANNEL);
            b.setOnlyAlertOnce(true);
            b.setColor(mContext.getResources()
                    .getColor(com.android.internal.R.color.system_notification_accent_color,
                            mContext.getTheme()));
            b.setContentTitle(item.description);
            b.setSubText(
                    BluetoothOppUtility.formatProgressText(item.totalTotal, item.totalCurrent));
            if (item.totalTotal != 0) {
                if (V) {
                    Log.v(TAG, "mCurrentBytes: " + item.totalCurrent + " mTotalBytes: "
                            + item.totalTotal + " (" + (int) ((item.totalCurrent * 100)
                            / item.totalTotal) + " %)");
                }
                b.setProgress(100, (int) ((item.totalCurrent * 100) / item.totalTotal),
                        item.totalTotal == -1);
            } else {
                b.setProgress(100, 100, item.totalTotal == -1);
            }
            b.setWhen(item.timeStamp);
            if (item.direction == BluetoothShare.DIRECTION_OUTBOUND) {
                b.setSmallIcon(android.R.drawable.stat_sys_upload);
            } else if (item.direction == BluetoothShare.DIRECTION_INBOUND) {
                b.setSmallIcon(android.R.drawable.stat_sys_download);
            } else {
                if (V) {
                    Log.v(TAG, "mDirection ERROR!");
                }
            }
            b.setOngoing(true);
            b.setLocalOnly(true);

            Intent intent = new Intent(Constants.ACTION_LIST);
            intent.setClassName(Constants.THIS_PACKAGE_NAME, BluetoothOppReceiver.class.getName());
            intent.setDataAndNormalize(Uri.parse(BluetoothShare.CONTENT_URI + "/" + item.id));

            b.setContentIntent(PendingIntent.getBroadcast(mContext, 0, intent, 0));
            mNotificationMgr.notify(NOTIFICATION_ID_PROGRESS, b.build());
        }
    }

    private void updateCompletedNotification() {
        long timeStamp = 0;
        int outboundSuccNumber = 0;
        int outboundFailNumber = 0;
        int outboundNum;
        int inboundNum;
        int inboundSuccNumber = 0;
        int inboundFailNumber = 0;

        // Creating outbound notification
        Cursor cursor =
                mContentResolver.query(BluetoothShare.CONTENT_URI, null, WHERE_COMPLETED_OUTBOUND,
                        null, BluetoothShare.TIMESTAMP + " DESC");
        if (cursor == null) {
            return;
        }

        final int timestampIndex = cursor.getColumnIndexOrThrow(BluetoothShare.TIMESTAMP);
        final int statusIndex = cursor.getColumnIndexOrThrow(BluetoothShare.STATUS);

        for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
            if (cursor.isFirst()) {
                // Display the time for the latest transfer
                timeStamp = cursor.getLong(timestampIndex);
            }
            int status = cursor.getInt(statusIndex);

            if (BluetoothShare.isStatusError(status)) {
                outboundFailNumber++;
            } else {
                outboundSuccNumber++;
            }
        }
        if (V) {
            Log.v(TAG, "outbound: succ-" + outboundSuccNumber + "  fail-" + outboundFailNumber);
        }
        cursor.close();

        outboundNum = outboundSuccNumber + outboundFailNumber;
        // create the outbound notification
        if (outboundNum > 0) {
            String unsuccessCaption = mContext.getResources()
                    .getQuantityString(R.plurals.noti_caption_unsuccessful, outboundFailNumber,
                            outboundFailNumber);
            String caption = mContext.getResources()
                    .getQuantityString(R.plurals.noti_caption_success, outboundSuccNumber,
                            outboundSuccNumber, unsuccessCaption);
            Intent contentIntent = new Intent(Constants.ACTION_OPEN_OUTBOUND_TRANSFER).setClassName(
                    Constants.THIS_PACKAGE_NAME, BluetoothOppReceiver.class.getName());
            Intent deleteIntent = new Intent(Constants.ACTION_COMPLETE_HIDE).setClassName(
                    Constants.THIS_PACKAGE_NAME, BluetoothOppReceiver.class.getName());
            Notification outNoti =
                    new Notification.Builder(mContext, OPP_NOTIFICATION_CHANNEL).setOnlyAlertOnce(
                            true)
                            .setContentTitle(mContext.getString(R.string.outbound_noti_title))
                            .setContentText(caption)
                            .setSmallIcon(android.R.drawable.stat_sys_upload_done)
                            .setColor(mContext.getResources()
                                    .getColor(
                                            com.android.internal.R.color
                                                    .system_notification_accent_color,
                                            mContext.getTheme()))
                            .setContentIntent(
                                    PendingIntent.getBroadcast(mContext, 0, contentIntent, 0))
                            .setDeleteIntent(
                                    PendingIntent.getBroadcast(mContext, 0, deleteIntent, 0))
                            .setWhen(timeStamp)
                            .setLocalOnly(true)
                            .build();
            mNotificationMgr.notify(NOTIFICATION_ID_OUTBOUND_COMPLETE, outNoti);
        } else {
            if (mNotificationMgr != null) {
                mNotificationMgr.cancel(NOTIFICATION_ID_OUTBOUND_COMPLETE);
                if (V) {
                    Log.v(TAG, "outbound notification was removed.");
                }
            }
        }

        // Creating inbound notification
        cursor = mContentResolver.query(BluetoothShare.CONTENT_URI, null, WHERE_COMPLETED_INBOUND,
                null, BluetoothShare.TIMESTAMP + " DESC");
        if (cursor == null) {
            return;
        }

        for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
            if (cursor.isFirst()) {
                // Display the time for the latest transfer
                timeStamp = cursor.getLong(timestampIndex);
            }
            int status = cursor.getInt(statusIndex);

            if (BluetoothShare.isStatusError(status)) {
                inboundFailNumber++;
            } else {
                inboundSuccNumber++;
            }
        }
        if (V) {
            Log.v(TAG, "inbound: succ-" + inboundSuccNumber + "  fail-" + inboundFailNumber);
        }
        cursor.close();

        inboundNum = inboundSuccNumber + inboundFailNumber;
        // create the inbound notification
        if (inboundNum > 0) {
            String unsuccessCaption = mContext.getResources()
                    .getQuantityString(R.plurals.noti_caption_unsuccessful, inboundFailNumber,
                            inboundFailNumber);
            String caption = mContext.getResources()
                    .getQuantityString(R.plurals.noti_caption_success, inboundSuccNumber,
                            inboundSuccNumber, unsuccessCaption);
            Intent contentIntent = new Intent(Constants.ACTION_OPEN_INBOUND_TRANSFER).setClassName(
                    Constants.THIS_PACKAGE_NAME, BluetoothOppReceiver.class.getName());
            Intent deleteIntent = new Intent(Constants.ACTION_COMPLETE_HIDE).setClassName(
                    Constants.THIS_PACKAGE_NAME, BluetoothOppReceiver.class.getName());
            Notification inNoti =
                    new Notification.Builder(mContext, OPP_NOTIFICATION_CHANNEL).setOnlyAlertOnce(
                            true)
                            .setContentTitle(mContext.getString(R.string.inbound_noti_title))
                            .setContentText(caption)
                            .setSmallIcon(android.R.drawable.stat_sys_download_done)
                            .setColor(mContext.getResources()
                                    .getColor(
                                            com.android.internal.R.color
                                                    .system_notification_accent_color,
                                            mContext.getTheme()))
                            .setContentIntent(
                                    PendingIntent.getBroadcast(mContext, 0, contentIntent, 0))
                            .setDeleteIntent(
                                    PendingIntent.getBroadcast(mContext, 0, deleteIntent, 0))
                            .setWhen(timeStamp)
                            .setLocalOnly(true)
                            .build();
            mNotificationMgr.notify(NOTIFICATION_ID_INBOUND_COMPLETE, inNoti);
        } else {
            if (mNotificationMgr != null) {
                mNotificationMgr.cancel(NOTIFICATION_ID_INBOUND_COMPLETE);
                if (V) {
                    Log.v(TAG, "inbound notification was removed.");
                }
            }
        }
    }

    private void updateIncomingFileConfirmNotification() {
        Cursor cursor =
                mContentResolver.query(BluetoothShare.CONTENT_URI, null, WHERE_CONFIRM_PENDING,
                        null, BluetoothShare._ID);

        if (cursor == null) {
            return;
        }

        for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
            BluetoothOppTransferInfo info = new BluetoothOppTransferInfo();
            BluetoothOppUtility.fillRecord(mContext, cursor, info);
            Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + info.mID);
            Intent baseIntent = new Intent().setDataAndNormalize(contentUri)
                    .setClassName(Constants.THIS_PACKAGE_NAME,
                            BluetoothOppReceiver.class.getName());
            Notification.Action actionDecline =
                    new Notification.Action.Builder(Icon.createWithResource(mContext,
                            R.drawable.ic_decline),
                            mContext.getText(R.string.incoming_file_confirm_cancel),
                            PendingIntent.getBroadcast(mContext, 0,
                                    new Intent(baseIntent).setAction(Constants.ACTION_DECLINE),
                                    0)).build();
            Notification.Action actionAccept = new Notification.Action.Builder(
                    Icon.createWithResource(mContext,R.drawable.ic_accept),
                    mContext.getText(R.string.incoming_file_confirm_ok),
                    PendingIntent.getBroadcast(mContext, 0,
                            new Intent(baseIntent).setAction(Constants.ACTION_ACCEPT), 0)).build();
            Notification public_n =
                    new Notification.Builder(mContext, OPP_NOTIFICATION_CHANNEL).setOnlyAlertOnce(
                            true)
                            .setOngoing(true)
                            .setWhen(info.mTimeStamp)
                            .addAction(actionDecline)
                            .addAction(actionAccept)
                            .setContentIntent(PendingIntent.getBroadcast(mContext, 0,
                                    new Intent(baseIntent).setAction(
                                            Constants.ACTION_INCOMING_FILE_CONFIRM), 0))
                            .setDeleteIntent(PendingIntent.getBroadcast(mContext, 0,
                                    new Intent(baseIntent).setAction(Constants.ACTION_HIDE), 0))
                            .setColor(mContext.getResources()
                                    .getColor(
                                            com.android.internal.R.color
                                                    .system_notification_accent_color,
                                            mContext.getTheme()))
                            .setContentTitle(mContext.getText(
                                    R.string.incoming_file_confirm_Notification_title))
                            .setContentText(info.mFileName)
                            .setStyle(new Notification.BigTextStyle().bigText(mContext.getString(
                                    R.string.incoming_file_confirm_Notification_content,
                                    info.mDeviceName, info.mFileName)))
                            .setSubText(Formatter.formatFileSize(mContext, info.mTotalBytes))
                            .setSmallIcon(R.drawable.bt_incomming_file_notification)
                            .setLocalOnly(true)
                            .build();
            Notification n =
                    new Notification.Builder(mContext, OPP_NOTIFICATION_CHANNEL).setOnlyAlertOnce(
                            true)
                            .setOngoing(true)
                            .setWhen(info.mTimeStamp)
                            .setContentIntent(PendingIntent.getBroadcast(mContext, 0,
                                    new Intent(baseIntent).setAction(
                                            Constants.ACTION_INCOMING_FILE_CONFIRM), 0))
                            .setDeleteIntent(PendingIntent.getBroadcast(mContext, 0,
                                    new Intent(baseIntent).setAction(Constants.ACTION_HIDE), 0))
                            .setColor(mContext.getResources()
                                    .getColor(
                                            com.android.internal.R.color
                                                    .system_notification_accent_color,
                                            mContext.getTheme()))
                            .setContentTitle(mContext.getText(
                                    R.string.incoming_file_confirm_Notification_title))
                            .setContentText(info.mFileName)
                            .setStyle(new Notification.BigTextStyle().bigText(mContext.getString(
                                    R.string.incoming_file_confirm_Notification_content,
                                    info.mDeviceName, info.mFileName)))
                            .setSubText(Formatter.formatFileSize(mContext, info.mTotalBytes))
                            .setSmallIcon(R.drawable.bt_incomming_file_notification)
                            .setLocalOnly(true)
                            .setVisibility(Notification.VISIBILITY_PRIVATE)
                            .setPublicVersion(public_n)
                            .build();
            mNotificationMgr.notify(NOTIFICATION_ID_PROGRESS, n);
        }
        cursor.close();
    }

    void cancelNotifications() {
        if (V) {
            Log.v(TAG, "cancelNotifications ");
        }
        mHandler.removeCallbacksAndMessages(null);
        mNotificationMgr.cancelAll();
    }
}
