Home | History | Annotate | Download | only in opp
      1 /*
      2  * Copyright (c) 2008-2009, Motorola, Inc.
      3  *
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions are met:
      8  *
      9  * - Redistributions of source code must retain the above copyright notice,
     10  * this list of conditions and the following disclaimer.
     11  *
     12  * - Redistributions in binary form must reproduce the above copyright notice,
     13  * this list of conditions and the following disclaimer in the documentation
     14  * and/or other materials provided with the distribution.
     15  *
     16  * - Neither the name of the Motorola, Inc. nor the names of its contributors
     17  * may be used to endorse or promote products derived from this software
     18  * without specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
     24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30  * POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 package com.android.bluetooth.opp;
     34 
     35 import java.io.File;
     36 import java.util.ArrayList;
     37 
     38 import android.bluetooth.BluetoothAdapter;
     39 import android.bluetooth.BluetoothDevice;
     40 import android.content.Context;
     41 import android.util.Log;
     42 
     43 import com.google.android.collect.Lists;
     44 
     45 /**
     46  * This class stores information about a batch of OPP shares that should be
     47  * transferred in one session.
     48  */
     49 /*There are a few cases: 1. create a batch for a single file to send
     50  * 2. create a batch for multiple files to send
     51  * 3. add additional file(s) to existing batch to send
     52  * 4. create a batch for receive single file
     53  * 5. add additional file to existing batch to receive (this only happens as the server
     54  * session notify more files to receive)
     55  * 6. Cancel sending a single file
     56  * 7. Cancel sending a file from multiple files (implies cancel the transfer, rest of
     57  * the unsent files are also canceled)
     58  * 8. Cancel receiving a single file
     59  * 9. Cancel receiving a file (implies cancel the transfer, no additional files will be received)
     60  */
     61 
     62 public class BluetoothOppBatch {
     63     private static final String TAG = "BtOppBatch";
     64     private static final boolean D = Constants.DEBUG;
     65     private static final boolean V = Constants.VERBOSE;
     66 
     67     public int mId;
     68     public int mStatus;
     69 
     70     public final long mTimestamp;
     71     public final int mDirection;
     72     public final BluetoothDevice mDestination;
     73 
     74     private BluetoothOppBatchListener mListener;
     75 
     76     private final ArrayList<BluetoothOppShareInfo> mShares;
     77     private final Context mContext;
     78 
     79     /**
     80      * An interface for notifying when BluetoothOppTransferBatch is changed
     81      */
     82     public interface BluetoothOppBatchListener {
     83         /**
     84          * Called to notify when a share is added into the batch
     85          * @param id , BluetoothOppShareInfo.id
     86          */
     87         public void onShareAdded(int id);
     88 
     89         /**
     90          * Called to notify when a share is deleted from the batch
     91          * @param id , BluetoothOppShareInfo.id
     92          */
     93         public void onShareDeleted(int id);
     94 
     95         /**
     96          * Called to notify when the batch is canceled
     97          */
     98         public void onBatchCanceled();
     99     }
    100 
    101     /**
    102      * A batch is always created with at least one ShareInfo
    103      * @param context, Context
    104      * @param info, BluetoothOppShareInfo
    105      */
    106     public BluetoothOppBatch(Context context, BluetoothOppShareInfo info) {
    107         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
    108         mContext = context;
    109         mShares = Lists.newArrayList();
    110         mTimestamp = info.mTimestamp;
    111         mDirection = info.mDirection;
    112         mDestination = adapter.getRemoteDevice(info.mDestination);
    113         mStatus = Constants.BATCH_STATUS_PENDING;
    114         mShares.add(info);
    115 
    116         if (V) Log.v(TAG, "New Batch created for info " + info.mId);
    117     }
    118 
    119     /**
    120      * Add one share into the batch.
    121      */
    122     /* There are 2 cases: Service scans the databases and it's multiple send
    123      * Service receives database update and know additional file should be received
    124      */
    125 
    126     public void addShare(BluetoothOppShareInfo info) {
    127         mShares.add(info);
    128         if (mListener != null) {
    129             mListener.onShareAdded(info.mId);
    130         }
    131     }
    132 
    133     /**
    134      * Delete one share from the batch. Not used now.
    135      */
    136     /*It should only be called under requirement that cancel one single share, but not to
    137      * cancel the whole batch. Currently we assume "cancel" is to cancel whole batch.
    138      */
    139     public void deleteShare(BluetoothOppShareInfo info) {
    140         if (info.mStatus == BluetoothShare.STATUS_RUNNING) {
    141             info.mStatus = BluetoothShare.STATUS_CANCELED;
    142             if (info.mDirection == BluetoothShare.DIRECTION_INBOUND && info.mFilename != null) {
    143                 new File(info.mFilename).delete();
    144             }
    145         }
    146 
    147         if (mListener != null) {
    148             mListener.onShareDeleted(info.mId);
    149         }
    150     }
    151 
    152     /**
    153      * Cancel the whole batch.
    154      */
    155     /* 1) If the batch is running, stop the transfer
    156      * 2) Go through mShares list and mark all incomplete share as CANCELED status
    157      * 3) update ContentProvider for these canceled transfer
    158      */
    159     public void cancelBatch() {
    160         if (V) Log.v(TAG, "batch " + this.mId + " is canceled");
    161 
    162         if (mListener != null) {
    163             mListener.onBatchCanceled();
    164         }
    165         //TODO investigate if below code is redundant
    166         for (int i = mShares.size() - 1; i >= 0; i--) {
    167             BluetoothOppShareInfo info = mShares.get(i);
    168 
    169             if (info.mStatus < 200) {
    170                 if (info.mDirection == BluetoothShare.DIRECTION_INBOUND && info.mFilename != null) {
    171                     new File(info.mFilename).delete();
    172                 }
    173                 if (V) Log.v(TAG, "Cancel batch for info " + info.mId);
    174 
    175                 Constants.updateShareStatus(mContext, info.mId, BluetoothShare.STATUS_CANCELED);
    176             }
    177         }
    178         mShares.clear();
    179     }
    180 
    181     /** check if a specific share is in this batch */
    182     public boolean hasShare(BluetoothOppShareInfo info) {
    183         return mShares.contains(info);
    184     }
    185 
    186     /** if this batch is empty */
    187     public boolean isEmpty() {
    188         return (mShares.size() == 0);
    189     }
    190 
    191     /**
    192      * Get the running status of the batch
    193      * @return
    194      */
    195 
    196     /** register a listener for the batch change */
    197     public void registerListern(BluetoothOppBatchListener listener) {
    198         mListener = listener;
    199     }
    200 
    201     /**
    202      * Get the first pending ShareInfo of the batch
    203      * @return BluetoothOppShareInfo, for the first pending share, or null if
    204      *         none exists
    205      */
    206     public BluetoothOppShareInfo getPendingShare() {
    207         for (int i = 0; i < mShares.size(); i++) {
    208             BluetoothOppShareInfo share = mShares.get(i);
    209             if (share.mStatus == BluetoothShare.STATUS_PENDING) {
    210                 return share;
    211             }
    212         }
    213         return null;
    214     }
    215 }
    216